1.多重继承的构造次序:基类构造函数按照基类构造函数在类派生列表中的出现次序调用,构造函数调用次序既不受构造函数初始化列表中出现的基类的影响,也不受基类在构造函数初始化列表中的出现次序的影响。

2.在单个基类情况下,派生类的指针或引用可以自动转换为基类的指针或引用,对于多重继承也是如此,派生类的指针或引用可以转换为其任意基类的指针或引用。

3.多重继承像单继承一样,用基类的指针或引用只能访问基类中定义(或继承)的成员,不能访问派生类中引入的成员。
   当一个类继承于多个基类的时候,那些基类之间没有隐含的关系,不允许使用一个基类的指针访问其他基类的成员。

4.如果用户自己定义了派生类自己的复制构造函数或赋值操作符,则用户要负责复制(赋值)所有的基类子部分。而对于编译器默认合成的派生类的复制构造函数或赋值操作符会自动复制或赋值基类部分。

5.在多重继承下,通常成员函数中使用的名字的查找首先在函数本身进行,如果不能在本地找到名字,就继续在成员的类中查找,然后依次查找每个基类。注意名字查找总是按照两个步骤进行的:(1)首先编译器找到一个匹配的声明(与参数、返回值、公有私有均没有关系,只与名字有关) (2)然后,编译器才确定所找到的声明是否合法。

6.虚继承是一种机制,类通过虚继承指出它希望共享其虚基类的状态。在虚继承下,对给定虚基类,无论该类在派生类层次中作为虚基类出现多少次,只继承一个共享的基类子对象。共享的基类子对象称为虚基类。
例如:

class istream: public virtual ios{ /*....*/ };
class ostream: virtual public ios{ /*....*/ };

7.通过用关键字virtual修改声明,将基类指定为通过虚继承派生:

class istream: public virtual ios{ /*....*/ };
class ostream: virtual public ios{ /*....*/ };

指定虚派生只影响从指定了虚基类的类派生的类。除了影响派生类自己的之外,它也是关于派生类与自己的未来派生类的关系的一个陈述。virtual说明符陈述了在后代派生类中共享指定基类的单个实例的愿望。
 
8.每个类只初始化自己的直接类。在应用于虚基类的时候,这个初始化策略会失败。如果使用常规规则,就可能会多次初始化虚基类。为了解决这个重复初始化问题,从具有虚基类的类继承的类对初始化进行特殊处理。在虚派生中,由最低层派生类的构造函数初始化虚基类。
      虽然由最低层派生类初始化虚基类,但是任何直接或间接继承虚基类的类一般也必须为该基类提供自己的初始化式。只要可以创建虚基类派生类类型的独立对象,该类就必须初始化自己的虚基类,这些初始化式只在创建中间类型的对象时使用。

例如:

在我们的层次中,可以有Bear、Raccoon或Panda类型的对象。创建Panda对象的时候,它是最低层派生类并控制共享的ZooAnimal基类的初始化;创建Bear对象(或Raccoon对象)的时候,不涉及更低层的派生类型。在这种情况下,Bear(或Raccoon)构造函数像平常一样直接初始化它们的ZooAnimal基类:

 Bear::Bear(std::string name,bool onExhibit):ZooAnimal(name,onExhibit,"Bear") { }
Raccoon::Raccoon(std::string name,bool onExhibit):ZooAnimal(name,onExhibit,"Raccoon") { }

虽然ZooAnimal不是Panda的直接基类,但是Panda构造函数也初始化ZooAnimal基类:

Panda::Panda(std::string name,bool onExhibit):ZooAnimal(name,onExhibit,"Panda"),Bear(name,onExhibit),Raccoon(name,onExhibit),Endangered(Endangered::critical),sleeping_flag(false) { }

当创建Panda对象的时候:
(1)首先使用构造函数初始化列表中指定的初始化式构造ZooAnimal部分。
(2)接下来,构造Bear部分。忽略Bear的用于ZooAnimal构造函数初始化列表的初始化式。
(3)然后,构造Raccoon部分。再次忽略ZooAnimal初始化式。
(4)最后,构造Panda部分。
如果Panda构造函数不显式初始化ZooAnimal基类,就使用ZooAnimal默认构造函数;如果ZooAnimal没有默认构造函数,则代码出错。

9.无论虚基类出现在继承层次中任何地方,总是在构造非基类之前构造虚基类:

class Character{ /*....*/ };
class BookCharacter: public Character{ /*....*/ };
class ToyAnimal{ /*...*/ };
class TeddyBear: public BookChatacter,public Bear,public virtual ToyAnimal{ /*...*/ };

按声明次序检查直接基类,确定是否在虚基类。例中,首先检查BookChatacter的继承子树,然后检查Bear的继承子树,最后检查ToyAnimal的继承子树。按从根类开始向下倒最低层派生类的次序检查每个子树。
    TeddyBear的虚基类的构造次序是先ZooAnimal再ToyAnimal。一旦构造了虚基类,就按声明次序调用非虚基类的构造函数:首先是BookChatacter,它导致调用Character的构造函数,然后是Bear。因此,为了创建TeddyBear对象,按下面次序调用构造函数:

 ZooAnimal();
ToyAnimal();
Character();
BookChatacter();
Bear();
TeddyBear();

在这里,由最低层派生类TeddyBear指定用于ZooAnimal和ToyAnimal的初始化式。
     在合成复制构造函数中使用同样的构造次序,在合成赋值操作符中也是按这个次序给基类赋值。保证调用基类的析构函数的次序与构造函数的调用次序相反。

C++ Primer 有感(多重继承与虚继承)的更多相关文章

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

    1.在多重继承中,基类的构造顺序与派生类列表中基类的出现顺序保持一致,与初始值列表中的顺序无关. 2.在C++11新标准中,允许派生类从它的一个或几个基类中继承构造函数.但是如果从多个基类中继承了相同 ...

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

    用于大型程序的工具 --多重继承与虚继承 引言: 大多数应用程序使用单个基类的公用继承,可是,在某些情况下,单继承是不够用的,由于可能无法为问题域建模,或者会对模型带来不必要的复杂性. 在这些情况下, ...

  3. C++中的多重继承与虚继承的问题

    1.C++支持多重继承,但是一般情况下,建议使用单一继承. 类D继承自B类和C类,而B类和C类都继承自类A,因此出现下图所示情况: A          A \          / B     C ...

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

    先来测试一些普通的多重继承.其实这个是显而易见的. 测试代码: //测试多重继承中派生类的构造函数的调用顺序何时调用 //Fedora20 gcc version=4.8.2 #include < ...

  5. 【c++】多重继承与虚继承

    派生类的构造函数初始化列表将实参分别传递给每个直接基类,其中基类的构造顺序与派生列表中基类的出现顺序保持一致,而与派生类构造函数初始化列表中基类的顺序无关. 类型转换与多个基类 编译器不会在派生类向基 ...

  6. C++学习之多重继承与虚继承

    一.多重继承 我们知道,在单继承中,派生类的对象中包含了基类部分 和 派生类自定义部分.同样的,在多重继承(multiple inheritance)关系中,派生类的对象包含了每个基类的子对象和自定义 ...

  7. C++继承,多重继承,虚继承的构造函数以及析构函数的调用顺序问题

    #include <iostream> using namespace std; class A{ int data_a; public: A(){ data_a = ; cout < ...

  8. Linux Debugging(四): 使用GDB来理解C++ 对象的内存布局(多重继承,虚继承)

    前一段时间再次拜读<Inside the C++ Object Model> 深入探索C++对象模型,有了进一步的理解,因此我也写了四篇博文算是读书笔记: Program Transfor ...

  9. C++虚继承作用

    C++虚继承可以防止多重继承产生的二义性问题. 虚继承,就是在被继承的类前面加上virtual关键字,这时被继承的类称为虚基类,如下面代码中的base类.虚继承在多重继承的时可以防止二义性. clas ...

随机推荐

  1. linux加入Windows域-------本人生产环境上线所用

    为什么说要linux加域呢!    因为之前在公司是做vmware的,然后呢vmware的horizon桌面云虚拟化都是通过域来管理的,开始使用的都是Windows桌面,后来开发的人员说要使用linu ...

  2. 函数&语法

    定义一个函数 加上一些算法,由自己定义的函数,以下是简单的规则: 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 (). 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参 ...

  3. node安装教程

    推荐安装教程博客: https://www.cnblogs.com/zhouyu2017/p/6485265.html

  4. 在Spring Boot框架下使用WebSocket实现消息推送

    Spring Boot的学习持续进行中.前面两篇博客我们介绍了如何使用Spring Boot容器搭建Web项目(使用Spring Boot开发Web项目)以及怎样为我们的Project添加HTTPS的 ...

  5. CentOS 7 下使用虚拟环境Virtualenv安装Tensorflow cpu版记录

    1.首先安装pip-install 在使用centos7的软件包管理程序yum安装python-pip的时候会报一下错误: No package python-pip available. Error ...

  6. 1小时学会JQuery

    ---------------------------------------------------------------------------------------------------- ...

  7. Zookeeper的安装配置及基本开发

    一.简介 Zookeeper 是分布式服务框架,主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务.状态同步服务.集群管理.分布式应用配置项的管理等等. ZooKeeper的目标就 ...

  8. Swift按照数组元素出现的次数及大小排序

    要求如下: 1.已知一个数组,按照单个元素在数组中出现的次数作为重新排序的依据,个数多的排在前面 2.相同个数时候,元素值大的排前面 例子: [1, 2, 2, 3, 5, 5] 经过计算得到的结果是 ...

  9. 一道有趣的Twitter技术面试题

    来自:http://blog.jobbole.com/50705/ 看下面这个图片” “在这个图片里我们有不同高度的墙.这个图片由一个整数数组所代表,数组中每个数是墙的高度.上边的图可以表示为数组[2 ...

  10. Android必知必会-App 常用图标尺寸规范汇总

    若移动端访问不佳,请使用 –> Github版 内容持续更新中,更新日期:2016-08-11 1. 程序启动图标(icon launcher) 放在mipmap-*dpi下,文件名为ic_la ...