类的内存布局小议

看代码:

class A

{

      int a;   

      virtual void hello(){}

};

class B : virtual public  A

{

      int a;   

      virtual void hello(){}

};

 

class C : virtual public A

{

      int a;   

      virtual void hello(){}

};

class D : public B, public C

{

      int a;   

      virtual void hello(){}

};

int main()

{

    cout<<"sizeof(A)"<<sizeof(A)<<endl;   

    cout<<"sizeof(B)"<<sizeof(B)<<endl;

    cout<<"sizeof(C)"<<sizeof(C)<<endl;

    cout<<"sizeof(D)"<<sizeof(D)<<endl;

}

输出结果是8 16 16 28,看看究竟是怎么来的

首先,类A里面有一个虚函数hello,那么这个类就多了一个隐藏的数据----指向虚函数表(vtbls)的指针(vptrs),我们假设是在32位系统下,所以A的大小为:4+4 = 8

对于类B,虚继承于A,那么除了类B的成员a和一个vptrs外,还有A的成员a以及vtpr,所以B的大小:4+4+4+4=16

CB分析相同。

那么D呢?首先它有自己的成员a以及一个vptrs,再有BC的成员avptrs,同时也存在A的成员aAvptrs,由于虚继承的关系D中只保留了A一份副本,这里需要提一下的是,Dvprts是和B或者Cvptrs可以共用,编译器优化,所以D本身的大小是4字节(成员a)

所以D的大小为

4          +4+4     +4+4    +4+4    = 28 byte

D本身       B           C             A

可以参照下图对象D的内存分配布局:

 具体的编译器优化可能有所不同。

 

另参考 More Effective C++》第24条款和《深入浅出MFC》第一篇第二章之类与对象大解剖。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值