5

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

    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

4

2 回答 2

15
A oA = *ptr1;

这会将所有成员变量复制到一个新的 A 对象中。vtable 指针不是普通的成员变量,不会被复制。因此,针对该对象调用的任何后续虚函数都将像它是 A 对象一样工作,因为它A 对象。

于 2010-08-13T19:27:51.510 回答
14

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

此外,大多数编译器都会优化oA.func()调用,使其根本不使用任何虚拟表。由于 的类型oA在编译时是已知的,因此oA.func()可以立即将调用定向到,A::func而无需使用任何虚拟表。

于 2010-08-13T18:37:00.090 回答