问题:如下代码输出结果是?
#include<iostream>
using namespace std;
class A {
protected:
int m_data;
public:
A(int data = 0) { m_data = data; }
int GetData() { return doGetData(); }
virtual int doGetData() { return m_data; }
};class B : public A {
protected:
int m_data;
public:
B(int data = 1) { m_data = data; }
int doGetData() { return m_data; }
};
class C : public B {
protected:
int m_data;
public:
C(int data = 2) { m_data = data; }
};
int main ()
{
C c(10);
cout << c.GetData() <<endl;
cout << c.A::GetData() <<endl;
cout << c.B::GetData() <<endl;
cout << c.C::GetData() <<endl;
cout << c.doGetData() <<endl;
cout << c.A::doGetData() <<endl;
cout << c.B::doGetData() <<endl;
cout << c.C::doGetData() <<endl;
return 0;
}
解析:输出结果是:
其它的都比较好理解,这里不赘述,主要是解答以下为啥第2个cout和第6个cout结果不一样。
cout << c.A::GetData() <<endl; // 1
cout << c.A::doGetData() <<endl; // 0
这里两个尽管都是调用A类中的函数,可是:一个是成员函数调用虚函数,一个是直接调用虚函数;
第一个函数是成员函数调用虚函数,本类(C类)中无该虚函数的定义声明。故找到最近的基类系(B类)虚函数;
第二个函数直接调用虚函数,直接去调用类(A类)中查找。故找到调用类结果就可以,找不到就编译失败(比如A类的doGetData如果是纯虚函数就会编译失败)。
如果说:cout << c.A::doGetData() <<endl; 还是会走到B类的doGetData()函数。那么请想一下这个问题:
cout << c.A::doGetData() <<endl; 还是会走到B类的doGetData()函数,那么上图2中的B类的Print()函数就不能调A::Print()函数,因为一旦允许这种写法,那么b.A::Print()这个调用必然是死循环。
详细解答参考:
https://blog.csdn.net/weixin_33743248/article/details/85889749