所以说class B的大小是12bytes

  代码二:


class A
{
    int a;
};
class B
{
    int b;
};

class C
{
};
class D
{
};
class E: public virtual A , public virtual B , public virtual C , public virtual D
{
};
void main()
{
    cout<<"sizeof E: "<<sizeof(E)<<endl;      //
}
 


  Class如果内含一个或多个virtual base class subobjects,将被分割为两部分:一个不变局部和一个共享局部.不变局部中的数据,不管后继如何衍化,总是拥有固定的offset(从object的开头算起),所以这一部分数据可以被直接存取。至于共享局部,所表现的是virtual base class subobject。这一部分的数据,其位置会因为每次的派生操作而有变化,所以它们只可以被间接存取。各家编译器实现技术之间的差异在于间接存取的方法不同。一般的布局策略是先安排好derived class的不变部分,然后再建立其共享部分.然而,这中间存在着一个问题:如何能够存取Class的共享部分呢?我这从微软的编译器来看它的内存布局。

  上面代码二输出的结果:

  class E的大小是不是有点怪,在命令行中输入:


cl test.cpp /d1reportSingleClassLayoutE

  如前面黑色字体标注一样,因为classE是多重虚继承,所以在内存中的布局是分为固定局部和共享局部,固定局部的大小int a,b 所以是8 bytes。我的上一篇博文(VC++对象布局的奥秘:虚函数、多继承、虚拟继承)对这个内存某型有个大概的讲解,在这不多言了。


E::$vbtable@:
1>   0 | 0
1>   1 | 4 (Ed(E+0)A)
1>   2 | 8 (Ed(E+0)B)
1>   3 | 12 (Ed(E+0)C)
1>   4 | 16 (Ed(E+0)D)


  一般都是把vbtable放在对象的前面,所以vbtable(virtual base class table)与对象首地址的偏移量一般是中间隔着vbtable,这个地方的4表示E的vbtable与虚基类A首地址的偏移量,同理,8,12,16这个不用我说了。既然这都给出了vbtable域虚基类的地址偏移量了,说明在E对象的内存中还是存在分配的空间。