虚拟继承与虚函数继承的内存布局

关于虚拟继承的内存分布参考如下文章:
在项目属性中的命令行加入以下语句,编译的时候显示了类的内存布局


测试程序(运行环境VS2008或VC6.0):
#include <iostream>
using namespace std;

class A
{
 char k[3];
public:
 virtual void aa(){};
};

class B :public virtual A
{
 char j[3];
public:
 virtual void bb(){};
};

class C :public virtual B
{
 char i[3];
public:
 virtual void cc(){};
};

void main()
{
 cout<<"sizeof(A):"<<sizeof(A)<<endl;
 cout<<"sizeof(B):"<<sizeof(B)<<endl;
 cout<<"sizeof(C):"<<sizeof(C)<<endl;
}
输出结果:
这个结果与《程序员面试宝典》的答案有出入,可能是编译器不同的原因吧
B的内存占用为                                             
虚函数表指针---->4字节
指向父类的虚类指针---->4字节
j[3]---->4字节(内存对齐)
A---->8字节
C类的占用空间可以此类推4*3+20=32但是注意, 虚拟继承爷爷永远在爸爸前面!(A在B前面)
改为直接继承的方式:
#include <iostream>
using namespace std;
class A
{
 char k[3];
public:
 virtual void aa(){};
};
class B :public  A  //去掉了virtual
{
 char j[3];
public:
 virtual void bb(){};
};
class C :public  B   //去掉了virtual
{
 char i[3];
public:
 virtual void cc(){};
};
void main()
{
 cout<<"sizeof(A):"<<sizeof(A)<<endl;
 cout<<"sizeof(B):"<<sizeof(B)<<endl;
 cout<<"sizeof(C):"<<sizeof(C)<<endl;
}

由此看出普通继承仅仅继承了数据,每个子类都有一个虚函数表指针

将虚函数改为普通函数,但是采用虚拟继承方式:
#include <iostream>
using namespace std;

class A
{
 char k[3];
public:
  void aa(){};   //去掉了virtual
};

class B :public virtual A
{
 char j[3];
public:
  void bb(){};   //去掉了virtual
};

class C :public virtual B
{
 char i[3];
public:
  void cc(){};    //去掉了virtual
};

void main()
{
 cout<<"sizeof(A):"<<sizeof(A)<<endl;
 cout<<"sizeof(B):"<<sizeof(B)<<endl;
 cout<<"sizeof(C):"<<sizeof(C)<<endl;
}

查看B的内存布局:

由此看出指向父类A虚表的指针vbptr占4字节
j[3]内存对齐后占4字节,k[3]占3字节,总共11字节
查看C的内存布局:

虚表指针4字节
i[3]  3字节+对齐2字节+A的数据k[3] 3字节 = 8字节
虚表指针4字节+B的数据j[3]内存对齐4字节
总共20字节
B类的基类A的数据在最后没有进行数据对齐,而C类的祖父A在前面进行了字节对齐且方式较为特殊,而且它的父类B进行了字节对齐,这个现象属于编译器的特性,略显特殊
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值