【C++笔记】继承体系下派生类的对象模型

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Wan_shibugong/article/details/80986464

继承

1、单继承

#include <iostream>
using namespace std


class Base
{
public:
    Base()
    {}
    int _b;
};

class Derived : public Base
{
public:
    Derived()
    {}
    int _d;
};
int main()
{
    Derived D;
    return 0;
}

2、多继承

#include <iostream>
using namespace std;

class A
{
public:
    int _a;
};

class B
{
public:
    int _b;
};

class D : public A,public B
{
public:
    int _d;
};

int main()
{
    D dd;
    dd._a = 1;
    dd._b = 2;
    dd._d = 4;
    return 0;
}

三个类在内存中的布局形式
这里写图片描述

3、菱形继承

存在二义性的问题

  • 通过作用域限定符
  • 通过菱形虚拟继承解决
//菱形继承
#include <iostream>
using namespace std;

class B
{
public:
    void test()
    {
        ;
    }
    int _b;
};

class C1:public B
{
public:
    int _c1;
};

class C2:public B
{
public:
    int _c2;
};

class D : public C1,public C2
{
public:
    int _d;
};

//解决方法  加作用域限定符
void test()
{
    D d;
    d.C1::_b = 1;
    d.C2::_b = 2;   //缺点,定义两个相同的变量,如果比较大,浪费空间
}

int main()
{
    cout<<sizeof(D)<<endl;

    D d;
    //d.test();     //不管是B类里面的函数函数变量都不可以直接访问,因为D类里面有两个相同的变量和函数
    //d._b = 10;      //菱形继承的二义性
    test();
    return 0;
}

菱形继承

4、虚拟继承

1、普通继承

  • 派生类对象大小8
  • 派生类对象模型 基类—-派生类
  • 编译器不会合成构造函数

    2、虚拟继承

  • 派生类对象大小8+4

  • 派生类对象模型 偏移量表格地址—派生类—基类
  • 编译器会合成构造函数
D d;  //合成构造函数,在调试时会在这里停下来
#include <iostream>
using namespace std;

class B
{
public:
    int _b;
};

class D : virtual public B
{
public:
    int _d;
};

int main()
{ 
    cout<<sizeof(D)<<endl;  //大小是12

    D d;
    d._b = 8;
    d._d = 9;
    return 0;
}

虚拟继承在内存中的存储
这里写图片描述

反汇编代码分析
这里写图片描述

这里写图片描述

五、菱形虚拟继承

用来解决菱形继承二义性的问题
函数和数据的二义性都可以解决

#include <iostream>
using namespace std;

class B
{
public:
    int _b;
};

class C1: virtual public B
{
public:
    int _c1;
};

class C2: virtual public B
{
public:
    int _c2;
};

class D : public C1,public C2
{
public:
    int _d;
};

int main()
{
    cout<<sizeof(D)<<endl;

    D d;
    d._b = 1;
    d._c1 = 2;
    d._c2 = 3;
    d._d = 4;
    return 0;
}

菱形虚拟继承对象模型
这里写图片描述

猜你喜欢

转载自blog.csdn.net/Wan_shibugong/article/details/80986464