C++多态分析
struct A { int a=1; }; struct B:A { int b=2; }; struct C:A { int c=3; }; struct D:B,C { int d=4; }; int main() { D d;
//d.a = 1; std::cout << sizeof(d) << endl;//20 }
菱形继承:基类有两个子类,有一个类继承了这两个基类的子类,就形成了菱形继承。这样继承会导致d类继承过来的字段冗余,B类会继承父类a字段构造后会拥有ab字段,C类会拥有ac字段,D类继承bc类会有abacd五个字段。当我们给a字段赋值时,将会报a不明确的错误,因为d对象有两个a字段。
分析完毕接下来看汇编:

进入D类的构造函数,进入构造会传入该类的首地址,根据首地址查找到该类在内存的地址,都是cc。
构造自身前会先call的是B类的构造。

call完A的构造B类的内存地址已经改变,1已经被赋值进内存。

在构造里B类构造里把b字段初始化为

初始化构造后d对象的内存分布就是有12134这四个字段。
解决方案:虚继承
struct A { int a=1; }; struct B: virtual A { int b=2; }; struct C:virtual A { int c=3; }; struct D:B,C { int d=4; }; int main() { D d; d.a = 1; std::cout << sizeof(d) << endl;//48 }
内存地址分布:

会包含两张虚表,啷个父类字段,一个基类字段,一个自身字段,虚表里存了28和18。我们计算一下第一张虚表和基类字段a的地址差和第二张虚表与字段a的地址差,会发现刚好是28和18,所以虚表里存的数值是基类字段和虚表的内存差,可以根据值寻找到共享字段的内存地址。

浙公网安备 33010602011771号