第七章 继承与派生
继承和派生的基本语法
//单继承
class 派生类名:继承方式 基类名
{
成员声明
}
class Derived:public Base
{
public:
Derived{}
~Derived{}
}
//多继承
class 派生类名:继承方式1 基类名1,继承方式2 基类名2
{
成员声明
}
class Derived:public Base1,private Base2
{
public:
Derived{}
~Derived{}
}
- 公有继承
基类成员对外访问属性在派生类中保持不变
派生类成员函数可以访问基类public和protected成员,不可访问private - 私有继承:将基类的原有的对外接口都封闭掉
基类public和protected成员都在派生类中对外访问属性变为private,类外不能直接调用,但是类体内可以,为了解决类外调用问题,需要在派生类中定义与基类同名的public函数,在该public函数体中调用从基类继承过来的已经成为private的成员函数。
派生类成员函数可以访问基类public和protected成员,不可访问private - 保护继承
基类public和protected成员(包括数据和函数)都在派生类中对外访问属性变为protected
派生类成员函数可以访问基类public和protected成员,不可访问private
保护成员的特点:
对于所在类的对象来说,它与private相同
对于其派生类来说,它与public相同
既方便数据隐藏,又方便继承,实现代码重用
不要重新定义继承过来的非虚函数,即父类和子类不要使用同名的非虚函数
派生类的构造函数
派生类的构造函数需要给基类的构造函数传递参数
//单继承时派生类构造函数的语法
派生类名::派生类名(基类所需形参,本类成员所需形参):基类名(参数表),本类成员初始化列表{
}
C::C(int i,int j):B(i),c(j){
//C继承自B,i和j分别为B,C的数据成员
}
//多继承时派生类构造函数的语法
派生类名::派生类名(参数表) :
基类名1(基类1初始化参数表),
基类名2(基类2初始化参数表),
...
基类名n(基类n初始化参数表),
本类成员初始化列表
{
//其他初始化;
};
初始化顺序按照继承顺序或者变量成员定义顺序,而不是初始化列表的顺序
- 调用构造函数时,先构造基类,再构造派生类
- 调用析构函数时,先析构派生类,再析构基类
虚基类
当派生类从多个基类派生,这些基类又有共同的基类,将产生冗余和二义性问题,虚基类可以解决此问题
虚基类并不是在声明基类时声明的,而是在声明派生类时,指定继承方式时声明的,第一级继承时就要将共同基类设计为虚基类如下,A作为B的虚基类
class B:virtual public A//第一级继承的时候就要加vitrual
1)在整个继承结构中,直接或间接继承虚基类的所有派生类,都必须在构造函数的成员初始化列表中为虚基类构造函数列出参数,如果未列出,则表示调用虚基类的默认构造函数
2)建立对象时,只有最远的派生类调用虚基类的构造函数,其他派生类忽略,故虚基类构造函数只调用一次