C++ Primer 笔记——多重继承与虚继承

时间:2021-06-21 20:47:32

1.在多重继承中,基类的构造顺序与派生类列表中基类的出现顺序保持一致,与初始值列表中的顺序无关。

2.在C++11新标准中,允许派生类从它的一个或几个基类中继承构造函数。但是如果从多个基类中继承了相同的构造函数(即形参列表完全相同)则程序将产生错误。这个时候这个类必须为该构造函数定义自己的版本。

class base
{
public:
base(int);
}; class base1
{
public:
base1(int);
}; class test :public base, public base1
{
public:
using base::base; // 从base继承构造函数
using base1::base1; // 从base1继承构造函数,此时已经报错 test(int); // 正确,上面的错误也消失
};

3.和往常一样,派生类的析构函数只负责清除派生类本身分配的资源,派生类的成员及基类都是自动销毁的。合成的析构函数体为空,析构函数的调用顺序正好与构造函数相反。

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

5.派生类对象可以转换到任意一种基类,但是对于重载函数可能产生二义性错误。

class base
{
}; class base1
{
}; class test :public base, public base1
{
}; void print(const base &b);
void print(const base1 &b); test t;
print(t); // 二义性错误

6.在多重继承中,对于名字的查找过程在所有直接基类中同时进行。如果名字在多个基类中都被找到,则对该名字的使用将具有二义性。这时候我们需要加上前缀限定符,或者在派生类中重新定义这个名字。

7.在默认情况下。派生类中含有继承链上每个类对应的子部分,如果某个类在派生过程中出现了多次,则派生类中将包含该类的多个子对象。我们可以通过虚继承解决这个问题,共享的基类子对象称为虚基类。虚派生只影响从指定了虚基类的派生类中进一步派生出的类,它不会影响派生类本身。虚派生中,虚基类是由最低层的派生类初始化的。

class base
{
}; class base1 :public virtual base
{
}; class base2 :virtual public base // virtual和public的顺序随意
{
}; class test :public base1, public base2 // test中只有一个base子对象
{
public:
test() :base() {} // 最低层的派生类可以直接初始化共享基类
};

8.含有虚基类的对象的构造顺序与一般的顺序稍有区别:首先使用提供给最低层派生类构造函数的初始值初始化该对象的虚基类子部分,接下来按照直接基类在派生列表中出现的次序对其进行初始化。

9.一个类可以有多个虚基类,此时,这些虚的子对象按照它们在派生列表中出现的顺序从左向右依次构造。合成的拷贝和移动构造函数按照完全相同的顺序执行,合成的赋值运算符中的成员也按照该顺序赋值。销毁顺序和构造顺序相反。