C++类对象布局

#include <iostream>
using namespace std;

// 多重继承构造执行顺序:
// 1、首先执行虚基类的构造函数,多个虚基类的构造函数按照被继承的顺序构造;
// 2、执行基类的构造函数,多个基类的构造函数按照被继承的顺序构造;
// 3、执行成员对象的构造函数,多个成员对象的构造函数按照申明的顺序构造;
// 4、执行派生类自己的构造函数;
// 5、析构以与构造相反的顺序执行;

// 继承关系:
//		X
//	Y		Z
//		A

class X
{
// 	virtual void func() { }		// 4,8,8,12
};

// C++使用虚拟继承(Virtual Inheritance),使得派生类如果继承基类多次,但只有一份基类的拷贝在派生类对象中。
class Y : public virtual X
{};

class Z : public virtual X
{};

class A : public Y, public Z
{};



class X1
{
public:
// 	virtual void func() { }		// 4,4,4,8
};

class Y1 : public X1
{};

class Z1 : public X1
{};

class A1 : public Y1, public Z1
{};


int main()
{
	cout << "sizeof(X): " << sizeof(X) << endl;	// 1
	cout << "sizeof(Y): " << sizeof(Y) << endl;	// 4  这个值和机器有关,也和编译器有关(4或8)
	cout << "sizeof(Z): " << sizeof(Z) << endl;	// 4
	cout << "sizeof(A): " << sizeof(A) << endl;	// 8

	cout << "sizeof(X1): " << sizeof(X1) << endl;	// 1
	cout << "sizeof(Y1): " << sizeof(Y1) << endl;	// 1 	
	cout << "sizeof(Z1): " << sizeof(Z1) << endl;	// 1
	cout << "sizeof(A1): " << sizeof(A1) << endl;	// 1

	return 0;
}

VS2005中,项目属性——>C++——>命令行——>附加选项,设置/d1reportAllClassLayout,编译时在输出中显示出类对象的布局:

1>class X size(1):
1> +---
1> +---
1>class Y size(4):
1> +---
1> 0 | {vbptr}
1> +---
1> +--- (virtual base X)
1> +---
1>Y::$vbtable@:
1> 0 | 0
1> 1 | 4 (Yd(Y+0)X)
1>vbi:    class  offset o.vbptr  o.vbte fVtorDisp
1>               X       4       0       4 0
1>class Z size(4):
1> +---
1> 0 | {vbptr}
1> +---
1> +--- (virtual base X)
1> +---
1>Z::$vbtable@:
1> 0 | 0
1> 1 | 4 (Zd(Z+0)X)
1>vbi:    class  offset o.vbptr  o.vbte fVtorDisp
1>               X       4       0       4 0
1>class A size(8):
1> +---
1> | +--- (base class Y)
1> 0 | | {vbptr}
1> | +---
1> | +--- (base class Z)
1> 4 | | {vbptr}
1> | +---
1> +---
1> +--- (virtual base X)
1> +---
1>A::$vbtable@Y@:
1> 0 | 0
1> 1 | 8 (Ad(Y+0)X)
1>A::$vbtable@Z@:
1> 0 | 0
1> 1 | 4 (Ad(Z+0)X)
1>vbi:    class  offset o.vbptr  o.vbte fVtorDisp
1>               X       8       0       4 0
1>class X1 size(1):
1> +---
1> +---
1>class Y1 size(1):
1> +---
1> | +--- (base class X1)
1> | +---
1> +---
1>class Z1 size(1):
1> +---
1> | +--- (base class X1)
1> | +---
1> +---
1>class A1 size(1):
1> +---
1> | +--- (base class Y1)
1> | | +--- (base class X1)
1> | | +---
1> | +---
1> | +--- (base class Z1)
1> | | +--- (base class X1)
1> | | +---
1> | +---
1> +---

由类对象布局可知:在虚拟继承时,在派生类对象中会有一个vbptr,而在基类中会有一个vbtable。同样方法可以在基类中添加一个虚函数,则可以看到派生对象中会有一个vfptr,而在基类中会有一个vftable。其中vbptr或者vfptr是在派生类定义对象是才有的,而vbtable和vftable则是在基类定义类时就有了。

另外在类不包含任何成员时,类对象仍然是占用空间的(VS2005是1个字节),这样是使得这个类的两个对象得以在内存中配置独一无二的地址。而在类中包含有成员变量或者虚函数时这个编译器安插的一个字节就不需要了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值