一、复习基础
1、C++的继承方式属于多继承,即一个子类可以同时继承多个父类。
class 派生类:继承方式 基类名称,继承方式 基类名称,……
{
//多个基类
}
2、派生类的生成过程
* 吸收基类成员;
* 改造基类成员;
* 添加新的成员。
二、访问控制
- 类的访问方式有三种:public、protected、private;
- 派生类中对于基类的成员访问有两种途径:
(1)派生类中的新增成员对于从基类继承的成员的访问;
(2)派生类外部(非类族内成员),通过派生类的对象访问从基类继承的成员。 - 公有继承(public)
当类的继承方式为公有继承时,原基类中的public、protected的成员访问属性不变,仍为public、protected;原基类中的private成员则不可直接访问。所谓的不可直接访问是指前面提到的两种途径都不可访问 - 保护继承(protected)
当类的继承方式为保护继承时,原基类中的public、protected的成员访问属性都变成protected;原基类中的private成员则不可直接访问。 - 私有继承(private)
当类的继承方式为私有继承时,原基类中的public、protected的成员访问属性都变成private;原基类中的private成员则不可直接访问。
从表面上看protected和private继承方式是相似的,在直接派生类中,所有成员的访问属性都是相同的。但是,如果派生类作为新的基类继续派生时,二者的区别就出来了。
例如,我们有Point类作为基类通过保护继承的方式派生出Line类,再由Line类派生出Rectangle类。当由Point类的public、protected的成员在Line中都变成了protected类型,再由Line通过私有继承的方式派生出Rectangle类,则原本Point中的public、protected的成员在Rectangle中变成了private类型。
当Point类作为基类通过私有继承的方式派生出Line类,再由Line类派生出Rectangle类。当由Point类的public、protected的成员在Line中都变成了private类型,再由Line通过私有继承的方式派生出Rectangle类,则原本Point中的public、protected的成员在Rectangle中变成了不可直接访问的成员。
三、类型兼容规则
类型兼容规则是指,在需要基类对象的任何地方,都可以使用其公有派生类的对象进行替代。
通过公有继承,派生类得到了基类的除了构造函数和析构函数以外的一切成员,因此在需要使用基类的地方,都可以是用派生类进行替换,这也是多态性的基础之一。
类型兼容规则中所指的替代包括以下的情况:
* 派生类的对象可以隐含转换为基类对象
* 派生类的对象可以初始化基类的引用
* 派生类的指针可以隐含转换为基类的指针
#include <iostream>
using namespace std;
class Base0
{
public:
void display()
{
cout<<"This is Base0"<<endl;
}
};
class Base1:public Base0
{
public:
void display()
{
cout<<"This is Base1"<<endl;
}
};
class Derived:public Base1
{
public:
void display()
{
cout<<"This is Derived"<<endl;
}
};
void fun(Base0 *b)
{
b->display();
}
int main()
{
Base0 base0;
Base1 base1;
Derived derived;
fun(&base0);
fun(&base1);
fun(&derived);
return 0;
}
最终结果三个全部输出This is Base0
四、派生类的构造和析构函数
1、构造函数
在进行派生的过程中,基类的构造函数和析构函数并没有传给派生类,因此我们需要定义派生类的构造函数来初始化基类的成员对象和派生类新增加的成员对象。
什么时候需要给派生类显式的声明构造函数呢?
当对基类进行初始化时,需要调用基类的带有形参表(即有形参)的构造函数时,派生类必须声明构造函数
派生类构造函数的形式为:
派生类名::派生类名(参数表):基类名1(基类1的初始化参数表),基类名2(基类2的初始化参数表),...,基类名n(基类n的初始化参数表),成员对象1(成员对象1的初始化参数表),...,成员对象n(成员对象n的初始化参数表)
{
构造函数的其他操作;
}
在构造函数的参数表中,需要对每个使用形参表的构造函数的基类,都需要给出初始化参数表,对于使用默认构造函数的基类,可以省略。
派生类的构造函数执行的过程如下:
- 调用各个基类的构造函数,调用的顺序为他们被继承时的声明的顺序;
- 对新增的成员对象进行初始化,调用顺序为他们在类中的声明顺序;
- 执行派生类的构造函数体中的内容
未完待续……