多继承与菱形继承

多继承

一个派生类继承了两个或多个基类,这样的继承关系叫做多继承。

#include<iostream>
using namespace std;

class B
{
public:
    B()
    {
        cout<<"B构造"<<endl;
    }
    ~B()
    {
        cout<<"B析构"<<endl;
    }

    int _b;
};

class B1
{
public:
    B1()
    {
        cout<<"B1构造"<<endl;
    }
    ~B1()
    {
        cout<<"B1析构"<<endl;
    }

    int _b1;
};

class D:public B,public B1
{
public:
    D()
    {
        cout<<"D构造"<<endl;
    }
    ~D()
    {
        cout<<"D析构"<<endl;
    }

    int _d;
};

int main()
{
    D d;
    d._b = 1;
    d._b1 = 2;
    d._d = 3;   
    return 0;
}

如上代码,派生类D以public权限继承了基类B和基类B1。

构造函数析构函数调用顺序

构造函数调用:首先调用派生类D的构造函数,执行顺序是按照类派生列表的顺序执行的。也就是说首先会执行基类B的构造函数,之后是B1的构造函数,最后时派生类D的构造函数。
析构函数的调用:与构造函数的执行顺序相反,先析构D,之后是B1,最后是B。
这里写图片描述

这里写图片描述

派生类对象空间模型

我们去内存里面看看数据是怎么存放的。
这里写图片描述

这里写图片描述
同样是按照类派生列表的顺序从上到下存放。

菱形继承

菱形继承,就是一个派生类D多继承了两个基类C1,C2。C1,C2又同时继承了同一个基类B。这样的继承关系就叫做菱形继承,也叫钻石继承。

这里写图片描述

class B
class C1:public B
class C2:public B
class D:public C1,public C2

#include<iostream>
using namespace std;

class B
{
public:
    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;
};

int main()
{
    D d;
    d.C1::_b = 5;
    d.C2::_b = 4;
    d._c1 = 1;
    d._c2 = 2;
    d._d = 3;
    return 0;
}

赋值结束后我们去看看内存中数据是怎么存放的
这里写图片描述

根据存放顺序我们就可以得出菱形继承的空间模型,由上到下分别是C1,C2,D。

这里写图片描述

由于C1,C2都继承了基类B,当我们直接由派生类对象d对基类B中的_b赋值时会出现下面的情况
这里写图片描述
这就是菱形继承存在的二义性问题。我们引入虚拟继承来解决这个问题。虚拟继承在下篇博客中详解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值