这是我的代码:
class Base {
public:
void foo() {
cout << "Base::foo" << endl;
}
};
class Derived : public Base {
public:
virtual void foo() {
cout << "Derived::foo" << endl;
}
};
int main()
{
Base* base = new Derived;
base->foo();
return 0;
}
这将调用Base::foo
。在使用此代码时,我很好奇发生了什么。我知道将为Derived
创建一个表,该表将包含指向foo
的指针,并且还有一个由Derived
构造函数初始化的指针,该指针将指向包含虚函数的表。
所以结果显示静态绑定正在发生,我很好奇这是怎么发生的?
我想我有点困惑,因为如果Base::foo
是虚拟的,那么Derived
v-table Base::foo
将被Dervied::foo
覆盖(现在就是这种情况) )。
编译代码时,编译器是否看到Base::foo
不是虚拟的并执行静态绑定?这是答案还是有另一个答案?
答案 0 :(得分:5)
调用在编译时解决,就像对非virtual
函数的任何其他调用一样。由于指针的类型为Base*
,并且Base
中的方法不是虚拟的,因此不会进行查找,并且它基本上已转换为
base->Base::foo();
答案 1 :(得分:0)
重载解析在编译时完成,无论是导致virtual
还是非虚函数。
然后生成调用该无歧义重载的代码,如果合适,将使用虚拟分派。
如果在Base
的上下文中执行此操作,则编译器不知道也不关心稍后的派生类可以声明具有相同名称的其他函数;它们肯定不是过载集的一部分。