虚继承对类大小的影响

//虚继承对类大小的影响

//virtual 存在,共享,间接

#include <iostream>
using namespace std;

#define PRT(x) cout<<x<<endl

class BB
{
public:
    int bb_;
};

class B1:virtual public BB
{
public:
    int b1_;
};

class B2:virtual public BB
{
public:
    int b2_;
};

class DD:public B1, public B2
{
public:
    int dd_;
};
int main()
{
    PRT(sizeof(BB));//4
    PRT(sizeof(B1));//12
    PRT(sizeof(B2));//12
    PRT(sizeof(DD));//24

    BB bb;
    PRT(&bb);
    PRT(&bb.bb_);
    B1 b1;
    PRT(&b1);
    PRT(&b1.b1_);
    PRT(&b1.bb_);

    long** p = (long**)&b1;
    PRT(p[0][0]);//0
    PRT(p[0][1]);//8
    PRT("------DD------");

    DD dd;
    PRT(&dd);
    PRT(&dd.b1_);
    PRT(&dd.b2_);
    PRT(&dd.dd_);//编译时刻已经决定了以下内存模型,所以dd.bb_是直接访问
    PRT(&dd.bb_);

    p = (long**)&dd;
    PRT(p[0][0]);//0
    PRT(p[0][1]);//20

    PRT(p[2][0]);//0
    PRT(p[2][1]);//12

    PRT("--------------");

    //通过基类指针访问虚基类的数据成员,不直接访问,只能间接访问,这需要运行时的支持
    BB* pp = &dd;
    pp->bb_;        //此时是间接访问,
    PRT(&dd);       //运行时会根据虚基类表找到dd中的虚基类部分的地址,
    PRT(&(pp->bb_));//将其赋值给pp
    return 0;
}



/*
虚继承后类的内存模型
    B1
+---------+  虚基类表指针指向虚基类表
|  vbptr  |---+      vbtl
+---------+   |   +---------+
|   b1_   |   |   |  0      |本类地址与虚基类表指针地址的差,如果没有虚函数(虚表)则为0
+---------+   +-->+---------+
|   bb_   |BB     |  8      |虚基类地址与虚基类表指针地址的差
+---------+       +---------+

    DD
+---------+
|  vbptr  |---+      vbtl
+---------+   |   +---------+
|   b1_   |   |   |  0      |
+---------+   +-->+---------+
|  vbptr  |---+   |  20     |
+---------+   |   +---------+
|   b2_   |   |
+---------+   |   +---------+
|   dd_   |   |   |  0      |
+---------+   +-->+---------+
|   bb_   |       |  12     |
+---------+       +---------+
*/

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值