C++中的菱形继承原理和解决方法

C++中的菱形继承原理和解决方法
如上图,菱形继承。
带来的主要问题:子类继承两份相同数据,导致资源的浪费以及毫无意义

解决方法:利用虚继承
在A和C继承Base类前加关键字virtual

class Base
{
int age;
};

//A继承base
class A:virtual public Base{};
//C继承base
class C:virtual public Base{};
//D继承A和C
class D:public A, public C{};

现在,Base中有属性a,如果不加virtual,那么现在进行如下操作:
D d;
d.A::age = 100;
d.C::age = 200;

这时候,会输出两个值,加上virtual,从A和C继承过来的就只会输出一个值200。

底层实现如下:
±—
0 | ±-- (base class A)
0 | | {vbptr}
| ±–
4 | ±-- (base class C)
4 | | {vbptr}
| ±–
±–
±-- (virtual base Base)
8 | age
±–

D::[email protected]@:
0 | 0
1 | 8 (D(A+0)Base)

D::[email protected]@:
0 | 0
1 | 4 (D(C+0)Base)

从A和C继承下来的是一个vbptr(virtual base pointer 虚基类指针,指向vbtable)指针,指向各自的vbtable,表中记录了一个偏移量,那么A+8,C+4,最后都得到了唯一的数据age,就解决了数据有两份的问题。

注:看底层关系的命令:
E : \cpp文件所在文件夹 > cl /d1 reportSingleClassLayoutSon 文件名.cpp
(用这个打开:Developer Command Prompt)