虚继承下对象大小的实验

首先看一下实验代码:
#include <iostream>
 
using namespace std;
 
class X {};
class Y : virtual public X {};
class Z : virtual public X {};
class A : public Y, public Z {};
int main()
{
    cout << "size X = " << sizeof(X) << endl;
    cout << "size Y = " << sizeof(Y) << endl;
    cout << "size Z = " << sizeof(Z) << endl;
    cout << "size A = " << sizeof(A) << endl;
    return 0;
}


运行结果:

下面就来讨论一下为什么会是这样的结果。

1、class X在内部没有任何数据的情况下,大小为1个字节。这样做是为了让class X对象在内存中占据空间并且不同的对象所占用空间不同,即用这一字节作为标识。

2、凡涉及到虚拟基类,编译器都会在类中安插某种形式的指针,指向跟虚基类有关的信息(要么直接指向虚基类对象,要么指向某个table),指针大小4字节。class Y和class Z原本应该继承class X的1字节数据。但有的编译器会对此做出优化,虚基类对象会被视作(注意,只是被视作,实际上还是以指针进行关联)派生类中的数据成员,所以现在派生类中有了成员,这1字节的标识便不会被插入。

3、class A继承class Y和class Z,后两者的大小为4字节,class A对象中存在两个类的实例,所以大小应该是8.

当class X中存在数据成员,那么结果又有所不同。下面是实验代码:
#include <iostream>
 
using namespace std;
 
class X {public: char x;};     // 有了数据
class Y : virtual public X {};
class Z : virtual public X {};
class A : public Y, public Z {};
int main()
{
    cout << "size X = " << sizeof(X) << endl;
    cout << "size Y = " << sizeof(Y) << endl;
    cout << "size Z = " << sizeof(Z) << endl;
    cout << "size A = " << sizeof(A) << endl;
    return 0;
}


运行结果:

1、class X中有了一个数据成员,所以占用1字节。

2、涉及到虚拟继承,class Y和class Z又会多出4字节空间,加上从class X继承过来的成员变量x,再加上4字节对齐,总大小为8字节。

3、class A中存在一份虚拟基类的实例,大小为1字节。注意,这里不会继承class Y和class Z的所有部分,由虚继承而生成的指针不会出现在class A中,所以之分别继承了两个类各4字节。9字节向上对齐到12,故class A总大小为12字节。

注意,这种实验的结果完全依赖于具体的编译器,VS2013中结果又有所不同。

环境:
Win7 + Code::Blocks

参考:
《深度探索C++对象模型》 P83-P88.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值