多重继承的虚函数表

时间:2014-08-27 08:59:52

标签: c++ multiple-inheritance virtual-functions

示例代码如下:

class A
{
public:
    int k;
    virtual int f();
};
class B:public virtual  A
{
public:
    virtual int a();
};
int main()
{
    cout<<sizeof(A)<<sizeof(B);
}

打印

  

8 12

似乎class B有自己的新虚函数表。

如果class A更改为:

class A
{
public:
    virtual int f();
};

打印

  

4 4

有人可以解释原因吗?

2 个答案:

答案 0 :(得分:1)

在子类B中,B是A的虚拟子类。因此,B在子对象A上有一个单独的vtbl指针(4个字节)。 因此,

sizeof(B object) 
= sizeof(A object) + sizeof (vtbl pointer of B)
= sizeof(int) + sizeof (vtbl pointer of A) + sizeof (vtbl pointer of B)
= 4 + 4 + 4
= 12

而且,

sizeof(A object)
= sizeof(int) + sizeof (vtbl pointer of A)
= 4 + 4
= 8

如果B是A的正常子类,

 sizeof(B object) 
    = sizeof(A object) 
    = sizeof(int) + sizeof (vtbl pointer of A) 
    = 4 + 4
    = 12

对于空类A,为sizeof分配的最小大小对象是vtbl = 4的sizeof指针 由于A在实例数据方面是空的,因此空类的虚拟继承不会增加对象的大小

答案 1 :(得分:0)

在类继承的上下文中,&#34;虚拟&#34;意味着&#34;在运行时确定&#34;。有两个单独的东西可以是虚拟的,并且实现必须以某种方式实现:

  • 虚拟函数,必须在运行时确定要调用的实际函数:x.f() - f?常见的实现涉及函数指针表。

  • 虚拟继承,其中直到运行时才知道虚拟基础子对象。实现必须提供一种机制来定位实际的基础对象:x.a = 10 - 其中a?这种常见的实现涉及指针偏移计算。

如果虚拟基类没有状态(这是相似的,但不等效,对于&#34;为空&#34;),则第二个用例变为空。由于没有数据成员的位置必须动态确定,因此实现不需要生成任何信息来执行此操作,对象也不需要存储相关的引用。

一个流行的C ++ ABI,Itanium ABI,详细描述了how virtuality is implemented。还有this popular article解释了这种实现。