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

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

时间: 2025-01-01 21:20:34

C++ Primer 笔记——多重继承与虚继承的相关文章

C++ Primer 学习笔记_95_用于大型程序的工具 --多重继承与虚继承

用于大型程序的工具 --多重继承与虚继承 引言: 大多数应用程序使用单个基类的公用继承,但是,在某些情况下,单继承是不够用的,因为可能无法为问题域建模,或者会对模型带来不必要的复杂性. 在这些情况下,多重继承可以更直接地为应用程序建模.多重继承是从多于一个直接基类派生类的能力,多重继承的派生类继承其所有父类的属性. 一.多重继承 1.定义多个类 为了支持多重继承,扩充派生列表: class Bear : public ZooAnimal { //... }; 以支持由逗号分隔的基类列表: cla

C++ Primer 学习笔记_96_用于大型程序的工具 --多重继承与虚继承[续1]

用于大型程序的工具 --多重继承与虚继承[续1] 四.多重继承下的类作用域 成员函数中使用的名字和查找首先在函数本身进行,如果不能在本地找到名字,就继续在本类中查找,然后依次查找每个基类.在多重继承下,查找同时检察所有的基类继承子树 -- 在我们的例子中,并行查找 Endangered子树和Bear/ZooAnimal子树.如果在多个子树中找到该名字,则那个名字的使用必须显式指定使用哪个基类;否则,该名字的使用是二义性的. [小心地雷] 当一个类有多个基类的时候,通过对所有直接基类同时进行名字查

C++ Primer 学习笔记_97_用于大型程序的工具 --多重继承与虚继承[续2]

用于大型程序的工具 --多重继承与虚继承[续2] 七.特殊的初始化语义 从具有虚基类的类继承的类对初始化进行特殊处理:在虚基类中,由最低层派生类的构造函数初始化虚基类.在ZooAnimal示例中,使用常规规则将导致Bear 类和 Raccoon类都试图初始化Panda对象的ZooAnimal类部分. 虽然由最低层派生类初始化虚基类,但是任何直接或间接继承虚基类的类一般也必须为该基类提供自己的初始化式.只要可以创建虚基类派生类类型的独立对象,该类就必须初始化自己的虚基类,这些初始化只在创建中间类型

C++ Primer学习笔记32_面向对象编程(3)--继承(三):多重继承、虚继承与虚基类

C++ Primer学习笔记32_面向对象编程(3)--继承(三):多重继承.虚继承与虚基类 一.多重继承 在C++语言中,一个派生类可以从一个基类派生,称为单继承:也可以从多个基类派生,称为多继承. 多重继承--一个派生类可以有多个基类 class <派生类名> : <继承方式1> <基类名1>,<继承方式2> <基类名2>,... { <派生类新定义成员> }; 可见,多继承与单继承的区别从定义格式上看,主要是多继承的基类多于一个

[转载]多重继承及虚继承中对象内存的分布

粘过来的效果还不错:) 本位通过不断地完善讲解多重继承及虚继承中对象内存的分布. 读的时候不要着急,第一遍会有些晕,第二遍就会好很多. 能帮助加深对多重继承及虚继承对象内存的分布情况. 多重继承及虚继承中对象内存的分布     这篇文章主要讲解G++编译器中虚继承的对象内存分布问题,从中也引出了dynamic_cast和static_cast本质区别.虚函数表的格式等一些大部分C++程序员都似是而非的概念. 本文是介绍C++的技术文章,假定读者对于C++有比较深入的认识,同时也需要一些汇编知识.

多重继承和虚继承的内存布局

这篇文章主要讲解虚继承的C++对象内存分布问题,从中也引出了dynamic_cast和static_cast本质区别.虚函数表的格式等一些大部分C++程序员都似是而非的概念.原文见这里(By Edsko de Vries, January 2006) 敬告: 本文是介绍C++的技术文章,假定读者对于C++有比较深入的认识,同时也需要一些汇编知识. 本文我们将阐释GCC编译器针对多重继承和虚拟继承下的对象内存布局.尽管在理想的使用环境中,一个C++程序员并不需要了解这些编译器内部实现细节,实际上,

大型程序的工具——多重继承与虚继承

一.多重继承与虚继承 1.多重继承 在派生类的派生列表中可以包含多个基类,每个基类包含一个可选的访问说明符. 多重继承的派生列表也只能包含已经定义过的类,而且这些类不能是final的.对于派生类能够继承的基类个数,C++没有进行特殊规定:但是在某个给定的派生列表中,同一个基类只能出现一次. 1)多重继承的派生类从每个基类中继承状态 在多重继承关系中,派生类的对象包含有每个基类的子对象. 2)派生类构造函数初始化所有基类 构造一个派生类的对象将同时构造并初始化它的所有基类子对象.与从一个基类进行的

多重继承,虚继承,MI继承中虚继承中构造函数的调用情况

先来测试一些普通的多重继承.其实这个是显而易见的. 测试代码: [cpp] view plain copy print? //测试多重继承中派生类的构造函数的调用顺序何时调用 //Fedora20 gcc version=4.8.2 #include <iostream> using namespace std; class base { public: base() { cout<<"base created!"<<endl; } ~base()

多重继承及虚继承中对象内存的分布

http://www.uml.org.cn/c++/201305163.asp 个人总结:多重继承时,对象中保存多个虚函数表指针, 虚拟继承时,对象中保存多个虚函数表指针,但被虚拟继承的基类对象在被继承的对象中只有一份,这个是靠共享其内容实现的.且共享的内容在子类对象的最后. 虚拟继承 为了避免上述Top类的多次继承,我们必须虚拟继承类Top. 1 class Top2 {3 public:4 int a;5 };67 class Left : virtual public Top8 {9 pu