在尝试更深入地分析 C++ 的继承机制时,我偶然发现了以下示例:
#include<iostream>
using namespace std;
class Base {
public:
virtual void f(){
cout << "Base.f" << endl;
}
};
class Left : public Base { //NOT VIRTUAL!!!
public:
void g(){
f();
}
};
class Right : public Base{
public:
virtual void f(){
cout << "Right.f" << endl;
}
};
class Bottom : public Left, public Right{
public:
Bottom(int arg){ }
//void f() { }
};
int main(int argc,char **argv)
{
Bottom* b = new Bottom(23);
b->g();
}
调用很明显
b->f()
是不明确的,所以对象 Bottom 上没有唯一的方法 f()
。现在,调用
b->g()
工作正常并打印
Base.f
嗯,据我所知:
- 静态类型是 Bottom,所以我们调用它的
g()
方法,因为它是非虚拟的 g()
方法继承自Left,所以我们称这个继承方法- 现在,Left 中的
g()
尝试调用虚方法f()
。根据 C++ 规范,我们调用动态类型指针(即 Bottom)的f()
方法
但 Bottom 没有方法 f()
... 至少不是唯一的。为什么这个程序执行 Left::Base::f()
而不是 Right::Base::f()
或者为什么它只是不声明调用 f()
与 Bottom 有歧义吗?
最佳答案
简短的回答是(如您所述),Bottom
没有方法 f()
,因此没有必要尝试调用它。
Bottom
包含两个子对象 Left
和 Right
。它们每个都继承自 Base
,因此 Bottom
包含成员函数 Left::f()
和 Right::f()
,但没有 Bottom::f()
。由于 Bottom 不会覆盖 Left::f()
(例如使用 Right::f()
),Base::f()
是 Left::g()
中唯一的最终覆盖器。
比照。来自 C++03 标准的 10.3.9 中的示例。
关于c++ - 虚拟和非虚拟继承的混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10166313/