C++ Primer 有感(多重继承与虚继承)
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 有感(多重继承与虚继承)的更多相关文章
- C++ Primer 笔记——多重继承与虚继承
1.在多重继承中,基类的构造顺序与派生类列表中基类的出现顺序保持一致,与初始值列表中的顺序无关. 2.在C++11新标准中,允许派生类从它的一个或几个基类中继承构造函数.但是如果从多个基类中继承了相同 ...
- C++ Primer 学习笔记_95_用于大型程序的工具 --多重继承与虚继承
用于大型程序的工具 --多重继承与虚继承 引言: 大多数应用程序使用单个基类的公用继承,可是,在某些情况下,单继承是不够用的,由于可能无法为问题域建模,或者会对模型带来不必要的复杂性. 在这些情况下, ...
- C++中的多重继承与虚继承的问题
1.C++支持多重继承,但是一般情况下,建议使用单一继承. 类D继承自B类和C类,而B类和C类都继承自类A,因此出现下图所示情况: A A \ / B C ...
- 多重继承,虚继承,MI继承中虚继承中构造函数的调用情况
先来测试一些普通的多重继承.其实这个是显而易见的. 测试代码: //测试多重继承中派生类的构造函数的调用顺序何时调用 //Fedora20 gcc version=4.8.2 #include < ...
- 【c++】多重继承与虚继承
派生类的构造函数初始化列表将实参分别传递给每个直接基类,其中基类的构造顺序与派生列表中基类的出现顺序保持一致,而与派生类构造函数初始化列表中基类的顺序无关. 类型转换与多个基类 编译器不会在派生类向基 ...
- C++学习之多重继承与虚继承
一.多重继承 我们知道,在单继承中,派生类的对象中包含了基类部分 和 派生类自定义部分.同样的,在多重继承(multiple inheritance)关系中,派生类的对象包含了每个基类的子对象和自定义 ...
- C++继承,多重继承,虚继承的构造函数以及析构函数的调用顺序问题
#include <iostream> using namespace std; class A{ int data_a; public: A(){ data_a = ; cout < ...
- Linux Debugging(四): 使用GDB来理解C++ 对象的内存布局(多重继承,虚继承)
前一段时间再次拜读<Inside the C++ Object Model> 深入探索C++对象模型,有了进一步的理解,因此我也写了四篇博文算是读书笔记: Program Transfor ...
- C++虚继承作用
C++虚继承可以防止多重继承产生的二义性问题. 虚继承,就是在被继承的类前面加上virtual关键字,这时被继承的类称为虚基类,如下面代码中的base类.虚继承在多重继承的时可以防止二义性. clas ...
随机推荐
- linux加入Windows域-------本人生产环境上线所用
为什么说要linux加域呢! 因为之前在公司是做vmware的,然后呢vmware的horizon桌面云虚拟化都是通过域来管理的,开始使用的都是Windows桌面,后来开发的人员说要使用linu ...
- 网络流24题第一题(luogu2796飞行员配对方案)
飞行员配对方案 二分图裸题,可以拿最大流怼. 题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 ...
- swing JTable
JTable 实例 import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayo ...
- PHP Misc. 函数
PHP 杂项函数简介 我们把不属于其他类别的函数归纳到杂项函数类别. 安装 杂项函数是 PHP 核心的组成部分.无需安装即可使用这些函数. Runtime 配置 杂项函数的行为受 php.ini 文件 ...
- Redis之(七)主从同步与集群管理
8.1 主从同步原理 像MySQL一样,Redis是支持主从同步的,而且也支持一主多从以及多级从结构. 主从结构,一是为了纯粹的冗余备份,二是为了提升读性能,比如很消耗性能的SORT就可以由从服务器来 ...
- OBJ文件格式分析工具: objdump, nm,ar
首先简要阐述关于gcc.glibc和 binutils模块之间的关系 一.关于gcc.glibc和binutils模块之间的关系 1.gcc(gnu collect compiler)是一组编译工具的 ...
- Android Studio 如何打JAR包
Android Studio 如何打JAR包 在eclipse中我们知道如何将一个项目导出为jar包,供其它项目使用. 在AS中可以通过修改gradle才处理. 我们新建一个项目MakeJar,在 ...
- 为什么函数式编程可以没有while?
以前想不通,今天在写代码时不知怎么的,偶然就发现了答案.. 比如说把某个字符串s中所有"00"及更长的'00'统统换为'0'.最后结果中不能包含'00'. 00001100--&g ...
- SRAM/DRAM,PROM/EPROM/EEPROM,NOR/NAND FLASH区别
SRAM/DRAM,PROM/EPROM/EEPROM,NOR/NAND FLASH区别 RAM / ROM 存储器 ROM和RAM指的都是半导体存储器,R ...
- Servlet - Upload、Download、Async、动态注册
Servlet 标签 : Java与Web Upload-上传 随着3.0版本的发布,文件上传终于成为Servlet规范的一项内置特性,不再依赖于像Commons FileUpload之类组件,因此在 ...