我很难理解为什么下面的代码会打印C :: f2而不是B :: f2。
当调用非虚函数时,实现必须使用 调用函数的对象的静态类型 确定要调用的正确函数。存储在vtable中的函数 由vptr访问将取决于动态类型 对象,而不是任何静态类型的引用或指针 正在访问。
我有点失落,在A :: f1里面有一个对f2的调用。编译器如何知道调用哪个方法?
我的说法:
我是对的吗?
struct A
{
void f1()
{
f2();
}
virtual void f2()
{
cout<<"A::f2"<<endl;
}
};
struct B:public A
{
virtual void f2()
{
cout<<"B::f2"<<endl;
}
};
struct C:public B
{
void f2()
{
cout<<"C::f2"<<endl;
}
};
int main()
{
C c1;
c1.f1();
return 0;
}
答案 0 :(得分:4)
每个成员函数都有一个隐式this
参数。 this
内f1
的静态类型始终为A * const
。对于任何成员函数都是如此。隐式对象参数的静态类型是封闭类,其中函数已定义。
f1
内的来电被解析为this->f2()
。由于这是通过指针调用,因此动态调度函数f2
。尽管f1
不是虚拟的,但总是会被静态调度调用。
通过编译器使用的任何机制(VTable是实现细节,而不是C ++标准本身强制要求),我们可以调用C::f2
。
所以你的假设需要一些修改,我会说。
按照您在评论中指定的方式回答您的问题。 C::f2
是虚拟的。您可能在覆盖它时省略了虚拟说明符,但没有&#34; unvirtualising&#34;它