现在的位置: 首页 > 综合 > 正文

inside C++笔记之C++数据布局

2013年10月09日 ⁄ 综合 ⁄ 共 1895字 ⁄ 字号 评论关闭

i.正常情况下的布局

数据布局如图:
 

 

ii.没有多态的继承

数据布局如图:
 

 

iii.有多态的继承


数据布局如图:
 
Ponit3d的vptr是使用从Ponit2d继承而来的,这时已经指向了Point3d的vbtl。如果在Point3d中重写了Point2d里的虚函数,则就是会在vbtl里替换成Point3d里的函数地址,
如果增加一个虚函数,则向vbtl增加一项,指向该函数的地址。

 

iv.多继承
如下代码:


数据布局如图:
 

对于一个多重派生类对象,将其地址指定给“最左端(也就是第一个)base class的指针”,
情况将和单一继承时相同,因为两者都指向相同的起始地址,需付出的成本只有地址的操作而已。至于第二个或第三个后继的base class的地址指定的操作,
则需要将地址修改:加上(或减去,如果downcast的话)介于中间的base class subject(s)大小。例如:
Vertex3d v3d;
Vertex* pv;
Pv = &v3d
在内部会转化为
Pv = (Vertex*)(((char*)&v3d) + sizeof(Point3d));

 

iv.虚拟继承

数据分布如图:
 
上述的四个类的大小分别为:12,20,20,32.(vs2008测试)
如果把Point2d的析构函数非虚,四个类的大小分别为:8,16,16,28.
这是因为Point2d,point3d,Vertex都没有vbtl,在它们的对象中也就没有了vptr.
虚继承实际继承链中只有一个实体,继承类对象中包含指向这个唯一实体的指针。

抱歉!评论已关闭.