C++菱形继承内存分布和解决方案分析

发布时间:2022-07-03 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了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字段。

分析完毕接下来看汇编:

C++菱形继承内存分布和解决方案分析

&nbsp;进入D类的构造函数,进入构造会传入该类的首地址,根据首地址查找到该类在内存的地址,都是cc。

C++菱形继承内存分布和解决方案分析

构造自身前会先call的是B类的构造。

C++菱形继承内存分布和解决方案分析

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

C++菱形继承内存分布和解决方案分析

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

 

C++菱形继承内存分布和解决方案分析

初始化构造后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
}

内存地址分布:

C++菱形继承内存分布和解决方案分析

 

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

脚本宝典总结

以上是脚本宝典为你收集整理的C++菱形继承内存分布和解决方案分析全部内容,希望文章能够帮你解决C++菱形继承内存分布和解决方案分析所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。