1. 继承体系中的每个类都可能在某个时刻成为“ 最低层的派生类”。 只要我们能创建虚基类的派生类对象, 该派生类的构造函数就必须初始化它的虚基类。

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

1.1 虚继承的对象的构造方式

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

eg. 当创建一个 Panda 对象时, Panda 位于派生的最低层并由它负责初始化共享的ZooAnimal 基类部分。 即使 ZooAnimal 不是 Panda 的直接基类, Panda 的构造函数也可以初始化 ZooAnimal:
step1. 使用 Panda 的构造函数初始值列表中提供的初始值构造虚基类 ZooAnimal
部分。
step2. 构造 Bear 部分。
step3.构造Raccoon 部分。
step4.构造第三个直接基类 Endangered。
step5.构造 Panda 部分

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

1.2 构造函数与析构函数的次序

一个类可以有多个虚基类。 此时, 这些虚的子对象按照它们在派生列表中出现的顺序从左向右依次构造。

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

编译器按照直接基类的声明顺序对其依次进行检査, 以确定其中是否含有虚基类。 如果有, 则先构造虚基类, 然后按照声明的顺序逐一构造其他非虚基类。 因此, 要想创建一个 TeddyBear 对象, 需要按照如下次序调用这些构造函数:

ZooAnimal ( );/ / Bear 的虚基类
ToyAnimal ( );/ / 直接虚基类
Character ( );/ / 第一个非虚基类的间接基类
BookCharacter ( )/ / 第一个直接非虚基类
Bear ( );/ / 第二个直接非虚基类
TeddyBear ( ) ;/ / 最低层的派生类

1.3 合成的拷贝和移动构造函数按照完全相同的顺序执行, 合成的赋值运算符中的成员也按照该顺序赋值。

1.4 对象的销毁顺序与构造顺序正好相反, 首先销毁TeddyBear 部分, 最后销毁 ZooAnimal 部分

C++ Primer 5th笔记(chap 18 大型程序工具)构造函数与虚继承相关推荐

  1. C++ Primer 5th笔记(chap 18 大型程序工具)使用命名空间成员

    1. 3种方法 using 声明 命名空间的别名( namespace alias) using 指示( using directive) 1.1 命名空间的别名 namespace cplusplu ...

  2. C++ Primer 5th笔记(chap 18 大型程序工具) 多重继承之构造函数、析构函数

    1. 继承的构造函数与多重继承 如果从多个基类中继承了相同的构造函数(即形参列表完全相同),则程序将产生错误 struct Basel {Basel () = default;Basel (const ...

  3. C++ Primer 5th笔记(chap 18 大型程序工具) 重载与命名空间

    1. using 声明或 using 指示能将某些函数添加到候选函数集 2. 对于接受类类型实参的函数来说, 其名字查找将在实参类所属的命名空间中进行.在这些命名空间中所有与被调用函数同名的函数都将被 ...

  4. C++ Primer 5th笔记(chap 18 大型程序工具) 类、 命名空间与作用域

    1. 命名空间内部名字的查找规则 由内向外依次查找每个外层作用域. 外层作用域也可能是一个或多个嵌套的命名空间, 直到最外层的全局命名空间查找过程终止. 只有位于开放的块中且在使用点之前声明的名字才被 ...

  5. C++ Primer 5th笔记(chap 18 大型程序工具)未命名的命名空间unnamed namespace

    1. 定义 关键字 namespace 后紧跟花括号括起来的一系列声明语句 1.1 生命周期 未命名的命名空间中定义的变量拥有静态生命周期: 它们在第一次使用前创建, 并且直到程序结束才销毁 未命名的 ...

  6. C++ Primer 5th笔记(chap 18 大型程序工具)内联命名空间 (inline namespace)

    1. inline必须出现在命名空间第一次出现的地方 inline namespace FifthEd {//... }//后续再打开命名空间的时候可以写inline也可以不写 namespace F ...

  7. C++ Primer 5th笔记(chap 18 大型程序工具)命名空间

    1. 问题:命名空间污染 namespace pollution 多个库将名字放置在全局命名空间 1.1 一般人的解决方法 起长名字 eg. class cplusplus_primer_Query ...

  8. C++ Primer 5th笔记(chap 18 大型程序工具)noexcept

    1. 通过提供 noexcept 说明 ( noexcept specification ) 指定某个函数不会抛出异常. 其形式是关键字 noexcept 紧跟在函数的参数列表后面 {// 紧跟在函数 ...

  9. C++ Primer 5th笔记(chap 18 大型程序工具)异常处理

    1. 异常处理 ( exception handling) 允许程序中独立开发的部分能够在运行时就出现的问题进行通信并做出相应的处理. 异常使得我们能够将问题的检测与解决过程分离开来. 程序的一部分负 ...

最新文章

  1. mysql同事包含_mysql 包含关系处理
  2. [新手必看] 17个常见的Python运行时错误
  3. iptables基础——链与表
  4. 深度|一篇文章解读人工智能的原理及产业升级机会
  5. 【MM】 基于收货的发票校验
  6. foreach的工作原理和深拷贝、浅拷贝
  7. LeetCode Algorithm 217. 存在重复元素
  8. C++异常以及错误处理
  9. 【MobaXterm】设置保持SSH连接
  10. mysql is blocked because of many connection errors
  11. el-table click事件多次触发_JavaScript从零开始——DOM事件编程(1)
  12. ASP.NET中的图片缓存
  13. RotateMenu简单地旋转菜单控件《IT蓝豹》
  14. linux下安装杰奇2.4,实现关关采集器远程采集详细教程
  15. Linux评分脚本,linux必看脚本大全
  16. 部署在服务器上的行驶证识别api接口
  17. Eclipse连接Hadoop集群(详细版)
  18. 概率论第六章——矩估计
  19. fx3u4ad一adp说明书_三菱PLC模块FX3U-4AD与FX3U-4AD-ADP的区别
  20. 点餐小程序实战教程03-店铺信息展示

热门文章

  1. CSS之定位布局(position,relative定位布局技巧)
  2. 职责链模式 php,php Chain of Responsibility 职责链模式
  3. Java虚拟机调用jni_JNI攻略之十一――启动虚拟机调用java类
  4. java 1.7升级到1.8_CentOS openJdk1.7升级1.8
  5. 排除计算机故障的顺序,计算机故障排除.ppt
  6. 2018年数据中心行业三大发展趋势
  7. 计算机硬盘冒烟了,电脑硬盘冒烟损坏了怎么办?
  8. ML之FE:数据随机抽样之利用pandas的sample函数对超大样本的数据集进行随机采样,并另存为csv文件
  9. 成功解决No handles with labels found to put in legend.
  10. BC之CM:区块链之共识机制——深入浅出以及国内外当下主流区块链平台共识机制纵向、横向比较相关配图