我的问题是参考this question,它解释了虚拟函数如何在对象切片的情况下工作,最终调用基类虚函数,Wikipedia article解释了派生类的虚拟表布局下面的代码
class A{
public:
virtual void func(){ cout<<"\n In A:func";}
};
class B:public A{
public:
virtual void func(){ cout<<"\n In B:func";}
};
main(){
A *ptr1 = new B();
A oA = *ptr1;
oA.func();
}
DerviedClassObjectB:
+0: pointer to virtual method table of B
virtual method table of B:
+0: B::func
以上程序输出“In A :: func”。
但如果没有用于B类的虚拟表知道基类A :: func,最终会调用A :: func
答案 0 :(得分:14)
“班级B
的虚拟桌”?类B
的虚拟表根本不涉及oA.func()
调用。对象oA
的类型为A
,这意味着其虚拟表是类A
的虚拟表。
此外,大多数编译器将优化oA.func()
调用,以便它根本不使用任何虚拟表。由于oA
的类型在编译时是已知的,因此oA.func()
调用可以立即定向到A::func
,而无需使用任何虚拟表。
答案 1 :(得分:14)
A oA = *ptr1;
这会将任何成员变量复制到新的A对象中。 vtable指针不是普通的成员变量,并且不被复制。因此,针对此对象调用的任何后续虚函数都将充当A对象,因为它 是A对象。