引用另一个 so question
考虑代码:
class Base {
public:
virtual void gogo(int a){
printf(" Base :: gogo (int) \n");
};
virtual void gogo(int* a){
printf(" Base :: gogo (int*) \n");
};
};
class Derived : public Base{
public:
virtual void gogo(int* a){
printf(" Derived :: gogo (int*) \n");
};
};
int main(){
// 1)
Derived * obj = new Derived ;
obj->gogo(7); // this is illegal because of name hiding
// 2)
Base* obj = new Derived ;
obj->gogo(7); // this is legal
}
对于情况 2)
调用 obj->gogo(7)
在运行时解析。
因为 obj->gogo(7)
是合法的。这似乎暗示 Derived
的 vtable 包含
指向
virtual void gogo(int a)
应该被隐藏。
我的困惑是,由于名称隐藏导致情况 1) 不合法,那么 2) 中的调用如何在运行时解决
a) Derived 的 vtable 是否包含指向 gogo(int) 的指针。
b) 如果 a) 不为真,虚函数的调用解析是否继续到基类的 vtable。
最佳答案
您混淆了虚函数调用和重载解析。
所有派生类都有包含所有虚函数的 vtables,来自基类和任何额外的自己的虚函数。这用于在运行时 解决调用,就像您的情况 2)。
在情况 1) 中,您在编译时 重载决策时遇到错误。由于名称隐藏,Derived
类只有一个可调用函数。您唯一的选择是使用 int*
调用该函数。
关于c++ - 关于名称隐藏和虚函数的混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10173211/