虚拟函数对象切片

问题描述 投票:0回答:2

我的问题是参考这个问题,它解释了虚拟函数在对象切片的情况下如何工作,最终调用基类虚拟函数。 维基百科文章解释了以下代码的派生类的虚拟表布局:

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();
}
DerivedClassObjectB:
  +0: pointer to virtual method table of B 

virtual method table of B:
  +0: B::func

上面的程序输出“In A::func”。但是,如果没有类

B
的虚拟表了解基类
A::func
,最终会调用
A::func
吗?

c++ function virtual vtable
2个回答
17
投票
A oA = *ptr1;

这会将所有成员变量复制到新的 A 对象中。 vtable 指针不是普通的成员变量,并且“不”被复制。因此,针对该对象调用的任何后续虚函数都将表现为它是 A 对象,因为它 A 对象。


14
投票
B

”?类

B
的虚拟表根本不参与
oA.func()
调用。对象
oA
具有类型
A
,这意味着它的虚拟表是类
A
的虚拟表。

此外,大多数编译器都会优化

oA.func()

调用,使其根本不会使用任何虚拟表。由于

oA
的类型在编译时已知,因此
oA.func()
调用可以立即定向到
A::func
,而无需使用任何虚拟表。
    

© www.soinside.com 2019 - 2024. All rights reserved.