C++继承模型的内存布局

派生类对象内存:自己的非静态数据成员+基类的数据成员,

           二者顺序并未强制规定。大部分编译器:基类成员先出现(虚基类除外)

1》非继承模型 独立的内存布局

      C++继承模型的内存布局_第1张图片

2》仅单一继承,无多态

   C++继承模型的内存布局_第2张图片 C++继承模型的内存布局_第3张图片

3》继承+多态

 例子:
      C++继承模型的内存布局_第4张图片
  

虚函数额外的负担:

虚函数增加:

1,类中,存放虚函数地址的虚表;

2,每个对象,插入虚指针vptr,指向相应的虚表,提供执行期的链接

3,加强构造函数,,构造函数设定vptr的初值,使其指向类对应的虚表(可能在派生类,基类中的构造函数中都重新设置vptr)

4,加强析构函数,析构函数摸消指向类的相关的虚表的vptr

vptr的位置:

1》  类对象尾端  ,用于C++早期

    C++继承模型的内存布局_第5张图片

2》  类的首端,用于 c++有了多重继承,虚继承后

   C++继承模型的内存布局_第6张图片

3》  基类的尾端

   C++继承模型的内存布局_第7张图片

3.3看出:对于单一继承,

基类,派生类的对象的相同点:从相同的地址开始

差别:在于派生类对象比较大。

point3d p3d;

point2d*p=&p3d;

派生类对象指定给基类的指针或引用,不需要编译器调整地址。

4》 多重继承  

1,对多重派生类对象,将其地址指定给最左端的基类的指针,情况和单一继承相同,因为二者指向相同的地址。

2,对于第二个或后继的基类的地址指定操作,需要修改地址:加减中间基类对象

   C++继承模型的内存布局_第8张图片

   C++继承模型的内存布局_第9张图片

 

5》虚拟继承

类含一个或多个虚基类时,可分割为:不变局部和共享局部

不变局部的数据:总有固定的偏移量(对象起始地址开始),直接存取

共享局部:    virtual基类部分,位置因为派生操作而变化,只可以间接存取

各家编译器的不同在于间接存取方法的不同.

间接存取的三种主流策略

策略1,先安排好派生类的不变部分,在建立共享部分

策略2:指针指向基类的模型  cfront编译器采用

    C++继承模型的内存布局_第10张图片

策略3:虚基类偏移量和虚函数混杂在一起,  正负值决定    sun编译器采用

虚基类最有效的运用形式:一个抽象的虚基类,没有任何数据成员

因为:数据成员存取效率---虚拟继承会增加成本



你可能感兴趣的:(C++继承模型的内存布局)