在尝试更深入地分析 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()
是模棱两可的,所以f()
对象底部没有唯一的方法。现在,打电话
b->g()
工作正常并打印
Base.f
好吧,据我所知:
- 静态类型是Bottom,所以我们称之为它的
g()
方法,因为它是非虚拟的 g()
方法是继承自Left,所以我们称这个继承方法- 现在,
g()
在 Left 尝试调用虚拟方法f()
。根据 C++ 规范,我们调用f()
指针的动态类型的方法(即底部)
但是底部没有方法f()
……至少不是一个独特的方法。为什么这个程序执行Left::Base::f()
而不是Right::Base::f()
或者为什么它根本没有说明对f()
底部的调用是模棱两可的?