继承与派生
使用背景:
当定义一个新的类 B 时,如果发现类 B 拥有某个已写好的类 A 的全部特性,此外还有类 A 没有的特性,那么就不必从头重写类 B,而是把类 A 作为一个“基类”(也称“父类”),把类 B 设计为基类 A 的一个“派生类”(也称“子类”)
于是就可以说从类 A “派生”出了类 B,也可以说类 B “继承”了类 A。
效果:
• 派生类是通过对基类进行扩充和修改得到的。
• 基类的所有成员自动也成为派生类的成员。
单继承、多重继承、重复继承
protected(成员访问控制)
• 对派生类的成员函数而言,它为public;对类的外部而言,它为private
• 即:protected成员只能由本类及其后代类的成员函数访问。
继承成员的访问控制
• 无论采用什么继承方式,基类的私有成员在派生类中都是不可访问的。
• 实际的访问权限取决于基类控制和继承控制中较低的那个
• 大多数情况下使用public继承
继承时的构造函数
• 基类的构造函数不会被继承,派生类中需要定义自己的构造函数。
• 派生类的构造函数中只需要对本类中新增成员进行初始化即可。
• 调用基类的构造函数对继承来的基类成员初始化
① 显式在初始化器列表中调用(注:不能在构造函数内调用!)
• 特别是需要使用基类的有参构造函数时
② 默认的隐式调用
• 编译时会在派生类构造函数初始化器中自动调用基类的默认构造函数
• 如果基类没有默认构造(包括 =delete),又没有显式调用,则编译错误
构造函数的调用次序
① 首先调用其基类的构造函数(调用顺序按照基类被继承时的声明顺序从左向右)
② 然后调用本类对象成员的构造函数(调用顺序按照对象成员在类中的声明顺序)。
③ 最后调用本类的构造函数。
析构函数的调用次序
析构函数的调用次序与构造函数的调用次序相反
① 首先调用本类的析构函数
② 然后调用本类对象成员的析构函数
③ 最后调用其基类的析构函数
综合示例