- 继承与派生的描述
- 继承与派生是同一过程不同的角度看
- 直接参与派生出某类的基类称为直接基类
- 基类的基类甚至更高层的基类称为间接基类
- 继承的目的:实现设计与代码的重用
- 吸收基类成员
- 默认情况下,派生类包含了全部基类中除构造和析构函数之外的所有成员
- C++11规定,可以用using语句继承基类构造函数
- 不同的继承方式的影响主要体现在
- 派生类成员对基类成员的访问权限
- 通过派生类对象对基类成员的访问权限
三种继承方式:公有、私有、保护继承
- 公有继承(public)
- 继承的访问控制
基类的public和protected成员:访问属性在派生类中保持不变
基类的private成员:不可直接访问
2.访问权限
派生类中的成员函数:可以直接访问基类中的public和protected成员,但不能直接访问private成员
通过派生类的对象:只能访问public成员
- 私有继承(private)
- 继承的访问控制
基类的public和protected成员:都以private身份出现在派生类中
基类的private成员:不可直接被访问
2.访问权限
派生类中的成员函数:可以直接访问基类中的public和protected成员,但不能直接访问private成员
通过派生类的对象:不能直接访问从基类继承的任何成员
- 保护继承(protected)
- 继承的访问控制
基类的public和protected 成员:都以protected身份出现在派生类中
基类的private成员:不可直接访问
2.访问权限
派生类中的成员函数:可以直接访问基类中的public和protected成员,但不能直接访问基类中的private成员
通过派生类的对象:不能直接访问从基类继承的任何成员,只能访问派生类新增的成员
- 类型转化
- 公有的派生类对象可以被当作基类的对象使用,反之则不可
派生类的对象可以隐含的转换为基类对象
派生类的对象可以初始化基类的引用
派生类的指针可以隐含转换为基类的指针
2.通过基类对象名、指针只能使用从基类继承的成员,不能使用派生类新增的成员
- 若不继承基类的构造函数
- 派生类新增成员:派生类定义构造函数初始化
- 继承来的成员:自动调用基类的构造函数进行初始化
- 派生类的构造函数需要给基类的构造函数传递参数
- 单继承时构造函数的定义语法
派生类名::派生类名(基类所需要的形参,本类成员所需要的形参):基类名(参数表),本类成员初始化列表 { //其他初始化 ;};
- 多继承时构造函数的定义语法
派生类名::派生类名(参数表):
基类名1(基类1初始化参数表),
基类名2(基类2初始化参数表),
......
基类名n(基类n初始化参数表),
本类成员初始化列表 { //其他初始化 ;};
- 派生类与基类的构造函数
- 当基类有默认构造函数时
派生类构造函数可以不向基类构造函数传递参数
构造派生类的对象时,基类的默认构造函数将被调用
2.如需执行基类中带参数的构造函数,派生类构造函数应为基类构造函数提供参数
- 构造函数的执行顺序
- 调用基类构造函数
顺序按照他们被继承时申明的顺序(从左到右)
2.对初始化列表中的成员进行初始化
顺序按照他们在类中定义的顺序
对象成员初始化时自动调用其所属类的构造函数,由初始化列表提供参数
3.执行构造函数体内的内容
- 析构函数的执行顺序
与构造函数的执行顺序相反,先析构本类对象,然后再析构基类对象。
- 当派生类与基类中有相同成员时
- 若未2特别限定,则通过派生类对象访问的是派生类中的同名成员
- 如果非要通过派生类对象访问基类中被隐藏的同名成员,应使用基类名和作用域操作符(::)来限定
- 虚基类
- 需要解决的问题
当派生类从多个基类派生,而这些基类又有共同的基类,则在访问此共同基类中的成员时,将产生冗余,并有可能因冗余带来不一致性
2.虚基类声明
Class B1::virtual public B
3.作用
主要用来解决多继承时可能发生的对同一基类继承多次而产生的二义性问题
为最远的基类提供唯一的基类成员,而不重复产生 多次复制
4.注意:在第一级继承时就要将共同基类设置为虚基类
- 虚基类及其派生类构造函数
- 建立对象时所指定的类称为最远派生类
- 虚基类的成员是由最远派生类的构造函数通过调用虚基类的构造函数进行初始化的
- 在整个继承结构中,直接或间接继承虚基类的所有派生类,都必须在构造函数的成员初始化列表中为虚基类的构造函数列出参数,如果未列出,则表示调用该虚基类的默认构造函数
- 在建立对象时,只有最远派生类的构造函数调用虚基类的构造函数,其他类对虚基类构造函数的调用被忽略