继承与多态
继承与派生
c++通过类派生来支持继承,被继承的类型称为基类(baseclass)或超类(superclass),而产生的类为派生类(derived class)或子类(subclass)。基类和派生类的集合称作类的层次结构(hierarchy).
定义:
class 派生类名 : 访问限定符 基类名1<,访问限定符 基类名2, ... , 访问限定符 基类名n>{
//成员表 新增的或替代父类的成员
}
同一个派生类可以同时继承多个基类,称为多重继承(multi-inheritance)
单继承(single-inheritance): 一个派生类只继承一个基类
先讨论单继承:
编写派生类的4个步骤:
- 吸收基类的成员, 除构造函数,析构函数,运算符重载函数,友元函数外所有的数据成员和函数成员全都成为派生类的成员
- 改造基类成员,当有的基类成员在新的应用中不合适时,可以进行改造,如果派生类声明一个和某个基类成员同名的成员,派生类中的成员会屏蔽基类同名的成员,类似函数中的局部变量屏蔽全局变量。 如果是成员函数,参数表和返回值完全一样时,称为同名覆盖(override),否则为重载
- 发展新成员,增加新的数据成员和函数成员,更适合新的应用
- 重写构造函数和析构函数
继承方式
继承方式分为三种,公有方式public,保护方式protected,私有方式private,如不显示的给出继承方式关键字,则默认为私有继承
在一层继承关系中,private和protected在行为上完全相同,但是当有两层或多层继承时,新保护派生的派生类可访问底层基类的公有和保护成员,而私有继承不可访问。
简单理解:会将基类中的访问限定符使用继承限定符进行进一步的访问限定
- public 继承会保留原访问形式
- priotected 会将public 进一步限定为protected
- private 会将public 和protected进一步限定为private
派生方式 | 基类中的访问限定符 | 在派生类中对基类的访问限定 | 在派生类对象外访问派生类对象的基类成员 |
---|---|---|---|
公有派生 public | public | public (可直接访问) | 可直接访问 |
公有派生 public | protected | protected(可直接访问) | 不可直接访问 |
公有派生 public | private | 不可直接访问 | 不可直接访问 |
私有派生 private | public | private(可直接访问) | 不可直接访问 |
私有派生 private | protected | private(可直接访问) | 不可直接访问 |
私有派生 private | private | 不可直接访问 | 不可直接访问 |
构造和析构函数
派生类的构造函数的定义:
派生类名:: 派生类 (参数总表): 基类名1(参数名表)<, 基类名2(参数名表), ..., 基类名2(参数名表)><,成员对象名1(成员对象参数名表)1, ... >){
// 新增成员的初始化}
在类体的声明中不需要写":"后面的部分。
派生类构造函数各部分的执行次序:
- 调用基类构造函数,按他们在派生类定义中的先后顺序依次调用, 若未显示声明则默认调用基类中的无参构造函数
- 调用新增成员对象的构造函数,按他们在类定义中排列的先后顺序依次调用
- 派生类的构造函数体中的初始化操作
在析构函数中只要处理好新增的成员就好。对于新增的成员对象和基类中的成员,系统会调用成员对象和基类的析构函数。析构函数各部分的执行次序与构造函数相反。
在实际中,成员对象的使用或者聚合是一种完善的封装,推荐将数据,数据的操作,资源的动态分配与释放封装在一个完善的子系统中,就像string。
虚基类
对于多继承(环状继承),A->D, B->D, C->(A,B),例如:
class D{