虚拟继承和多重继承中类对象的大小



菱形继承图示:




本实例以经典的菱形多重继承、虚继承为例,研究类对象的大小,假设有以下的虚继承实例代码:




<span style="font-size:14px;">class Point2d
{
public:
	float _x,_y;
};
class Vertex : public virtual Point2d
{
public:
	Vertex *next;
};
class Point3d : public virtual Point2d
{
public:
	float _z;
};
class Vertex3d : public Vertex,public Point3d
{
public:
	float mumble;
};
void main()
{
	cout << "Point2d: "<< sizeof(Point2d)<<endl;
	cout << "Point3d: "<< sizeof(Point3d)<<endl;
	cout << "Vertex: "<< sizeof(Vertex)<<endl;
	cout << "Vertex3d: "<< sizeof(Vertex3d)<<endl;

}</span>








本程序在VS2010下做测试,通过查看类 Vertex3d 类的内存布局如下:



从上图可以清晰的看到:sizeof(Vertex3d) = 28;

标号1处是 class Vetex内存布局,占用 8 字节空间,vbptr 是指向 virtual base Point2d 的指针;next是其自身的数据成员

标号2处是 class Point3d内存布局,占用 8字节空间,vbptr同样是指向 virtual base Point2d的指针,_z是该类自身的数据成员

标号3处是 class Vertex3d自身的数据成员 mumble,由于上图就是class Vertex3d自身的布局图,大小是 28

标号4处是 class Point2d内存布局,占用8字节空间,_x,_y是该类自身的数据成员


可见,class Vertex3d 虚继承自 Vertex和Point3d,自身数据组成有四部分:

(1)Vertex,如上图标号1所示

(2)Point3d,如上图标号2所示

(3)自身的数据成员 mumble,如图标号3所示

(4)Point2d,如图标号4所示


在多层的虚继承中,最后继承的类(例如本例的Verted3d类),将重复继承的基类(Point2d)部分保留一份,它的上层基类(Vertex,Point3d)内部只是保留自身的数据成员和一个指向虚基类的指针。




如果在基类中加入虚函数,研究指向虚基类的指针和虚函数表指针是否会重合,代码如下:




class Point2d
{
public:
	virtual void func(); //加入一个虚函数
	float _x,_y;
};
class Vertex:public virtual Point2d
{
public:
	Vertex *next;
};
class Point3d:public virtual Point2d
{
public:
	float _z;
};
class Vertex3d:public Vertex,public Point3d
{
public:
	float mumble;
};
void main()
{
	cout << "Point2d: "<< sizeof(Point2d)<<endl;
	cout << "Point3d: "<< sizeof(Point3d)<<endl;
	cout << "Vertex: "<< sizeof(Vertex)<<endl;
	cout << "Vertex3d: "<< sizeof(Vertex3d)<<endl;

}







class Vertex3d的内存布局:



class Vertex的内存布局:




总结:最初始的基类(例如.Point2d)的数据保留在最后继承的类(例如.Vertex3d)中,中间的类(例如.Vertex、Point3d)只是保留自身的数据和一个指向虚基类的指针而已。描述起来词不达意的感觉,详细请看《深入理解C++对象模型》




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值