多重继承

吃可爱长大的小学妹 提交于 2019-11-29 00:07:50

在派生类的派生列表中可以包含多个基类:

class Bear : public ZooAnimal { /* ... */ };
class Panda : public Bear, public Endangered { /* ... */ };

每个基类包含一个可选的访问修饰符。一如往常,如果访问说明符被忽略了,则关键字class对应的默认访问说明符是private,关键字struct对应的是public。

  和只有一个基类继承一样,多重继承的派生列表也只能包含已经被定义过的类,而且这些类只能是final的。对于派生类能够继承的基类个数,C++没有进行特殊的规定;但是在某个给定的派生类表中,同一个基类只能出现一次。

多重继承的派生类从每个基类中继承状态

  在多重继承关系中,派生类的对象含有每个基类的子对象。

派生类构造函数初始化所有基类

  构造一个派生类对象将同时构造并初始化它的所有基类子对象。与从一个基类进行派生一样,多重继承的派生类的构造函数初始值也只能初始化它的直接基类。

//显示地初始化所有基类
Panda::Panda(std::string name, bool onExhibit) 
    : Bear(name, onExhibit, "Panda"),
      Endangered(Endangered::critical) {}
//隐式地使用Bear的默认构造函数初始化Bear子对象
Panda::Panda() : Endangered(Endangered::critical) {}

派生类的构造函数初始值列表将实参分别传递给每个直接基类。其中基类的构造顺序与派生列表中基类的出现顺序保持一致,而与派生类构造函数初始值列表中基类的顺序无关。

一个Panda对象按照如下次序进行初始化:

  • ZooAnimal是整个继承体系的最终基类,Bear是Panda的直接基类,ZooAnimal是Bear的直接基类,所以首先初始化ZooAnimal。
  • 接下来初始化Panda直接基类Bear。
  • 然后初始化Panda的第二个直接基类Endangered。
  • 最后初始化Panda。

继承的构造函数与多重继承

  在C++11新标准中,允许派生类从它的一个或多个基类中继承构造函数。但是如果从多个基类中继承了相同的构造函数(即形参列表完全相同),则程序将产生错误:

struct Base1
{
    Base1() = default;
    Base1(const std::string&);
    Base1(std::shared_ptr<int>);
};

struct Base2
{
    Base2() = default;
    Base2(const std::string&);
    Base2(int);
};

//错误:D1试图从两个基类中都继承D1::D1(const std::string&)
struct D1 : public Base1, public Base2
{
    using Base1::Base1; //从Base1继承构造函数
    using Base2::Base2; //从Base2继承构造函数
};

如果一个类从它的多个基类中继承了相同的构造函数,则这个类必须为该构造函数定义它自己的版本:

struct D2 : public Base1, public Base2
{
    using Base1::Base1; //从Base1继承构造函数
    using Base2::Base2; //从Base2继承构造函数
    //D2必须自定义一个接受string的构造函数
    D2(const std::string &s) : Base1(s), Base2(s) {}
    D2() = default; //一旦D2定义了它自己的构造函数,则必须出现
};

析构函数与多重继承

  和往常一样,派生类的析构函数只负责清除派生类本身分配的资源,派生类的成员及其基类都是自动销毁的。合成的析构函数体为空。

  析构函数的调用顺序正好与构造函数相反,在我们的例子中,析构函数的调用顺序是~Panda、~Endangered、~Bear、~ZooAnimal。

多重继承的派生类的拷贝和移动操作

  与只有一个基类的继承一样,多重继承的派生类如果定义了自己的拷贝/赋值构造函数和赋值运算符,则必须在完整的对象上执行拷贝、移动或赋值操作。只有当派生类使用的是合成版本的拷贝、移动或赋值成员时,才会自动对其基类部分执行这些操作。在合成的拷贝控制成员中,

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!