虚继承与内存布局

单继承:单个基类
多继承:多个基类
菱形继承:
虚继承与内存布局
虚继承与内存布局

给出一个基类指针指向派生类对象:B* p=new D(10);
则D的内存布局为:
虚继承与内存布局
在图中我们可以看到有两个A的内存块造成了内存重复,浪费了内存,此时就引入了虚继承和虚基类
虚基类:虚继承中的基类
虚继承:加在可能发生内存重复的直接继承上
加上虚继承后,B和C中出现了一个指针,因为指针在编译阶段生成,但是在编译阶段A还未实例化没有地址可以指向,所以该指针指向关于A的一个结构体即虚基类表,存放着偏移量,可以用于找到A
虚继承与内存布局
虚继承与内存布局
因为A部分是在D作用域下,所以D的构造函数中一定要调用A的构造函数!

此时的内存布局:
虚继承与内存布局

虚继承与内存布局
此时的内存布局:
虚继承与内存布局
如果交换一下继承的顺序,内存布局:
虚继承与内存布局
因为非虚基类的布局优先于虚基类,所以布局中A部分和E部分的顺序不会改变。
虚基类的处理顺序和继承顺序有关:
虚继承与内存布局
此时因为继承顺序是 B E C,而E和C是虚继承,所以E的布局在A的布局之前!