2013亚马逊面试题--虚继承的内存模型分析

发表于:2013-1-18 09:36

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:wangqiulin123456    来源:51Testing软件测试网采编

  所以说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对象的内存中还是存在分配的空间。

53/5<12345>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号