-继承和派生
一继承(继承就是从先辈处得到属性和行为特征)
1 派生类的声明
class 派生类名∶[继承方式] 基类名
{
派生类新增的数据成员和成员函数
};
2 基类成员在派生类中的访问属性
3 派生类对基类成员的访问规则
1)内部访问 由派生类中新增的成员函数对基类继承来的成员的访问
2)对象访问 在派生类外部,通过派生类的对象对从基类继承来的成员的访问
3)
1. 私有继承的访问规则
2)公有继承的访问规则
.
3)保护继承的访问规则
4 派生类的构造函数和析构函数
1)
派生类构造函数和析构函数的执行顺 序
当创建派生类对象时:
基类的构造函数---派生类的构造函数;
当撤消派生类对象时:
派生类的析构函数---基类的析构函数。
注:当基类含有带参数的构造函数时,派生类必须定义构造函数,并缀上“:基类名(参数表) ”,以提供把参数传递给基类构造函数的途径。
派生类构造函数的一般格式为
派生类名(参数总表):基类名(参数表)
{
派生类新增成员的初始化语句
}
说明: (1)可以将派生类构造函数定义在类的外部,而在类体内只写该函数的声明
(2) 若基类使用不带参数的构造函数或带缺省参数的构造函数,则在派生类中定义构造函数时可略去“∶基类(参数表)”;
(3)如果派生类的基类也是一个派生类,每个派生类只需负责其直接基类的构造,依次上溯
(4) 在执行派生类的析构函数时,系统会自动调用基类的析构函数,对基类的对象进行清理
问题:当派生类中含有对象成员时,其构造函数应该如何构造?
当派生类中含有对象成员时,其构造函数的一般形式为:
派生类名(参数总表):基类名(参数表0),对象名成员1(参数表1),…,对象成员名n (参数表n)
{
//派生类新增成员的初始化语句 ..
}
即
定义派生类对象时,构造函数的执行顺序如下:
·调用基类的构造函数;
·调用对象成员的构造函数;
·执行派生类的构造函数体。
撤消对象时,析构函数的调用顺序与构造函数的调用顺序正好相反。
.调用派生类的析构函数;
. 调用对象成员的析构函数;
. 调用基类的析构函数
5 调整基类成员在派生类中的访问属性的其他方法
1)同名成员(C++语言允许在派生类中说明的成员与基类中的成员名字相同)
为了在派生类中使用基类的同名成员,必须在该成员名之前加上基类名和作用域标 识符“::”,
? 能否使私有继承的派生类的对象访问基类的公有成员或保护成员
访问声明:
把基类的保护成员名或公有成员名直接写到私有派生类定义式中的同名段中,
同时在成员名前冠以“基类名∷”
例如:
#include<iostream.h>
class A{
int x;
public:
A(int x1){x=x1;}
void print( ){cout<<"x="<<x;} };
class B: private A{
int y;
public:
B(int x1,int y1):A(x1){y=y1;}
A::print; //访问声明
};
main( )
{ B b(10,20);
b.print( );
return 0; }
说明:(1)访问声明中只能含不带类型和参数的函数名或变量名
(2) 数据成员也可以使用访问声明
(3) 访问声明不能改变类成员在基类中原来的性质
二 多继承与虚基类
1 多继承(当一个派生类具有多个基类时,这种派生方法称为多基派生或多继承)
多重继承声明的一般形式如下:
class 派生类名:继承方式1 基类名 1,…, 继承方式n 基类名n
{
派生类新增的数据成员和成员函数
};
2 多继承派生类的构造函数与析构函数
多继承构造函数定义的一般形式如下:
派生类名(参数总表):基类名1(参数表1),基类名2(参数表2),…,基类名n(参数表)
{
派生类新增成员的初始化语句
}
注:
多继承构造函数的执行顺序与单继承构造函数的执行顺序相同:
· 先执行基类的构造函数;
· 再执行对象成员的构造函数;
· 最后执行派生类构造函数。
析构函数的执行顺序则刚好与构造函数的执行顺序相反。
3 虚基类
1)作用
如果一个派生类是从多个基类派生出来的,而这些基类又有一个共同的基类,
则在这个派生类中访问这个共同的基类中的成员时,可能会产生二义性
所以引入虚基类 使从不同的路径继承的基类的成员在内存中只拥有一个拷贝