目录
1、派生类构造函数的定义
1.派生类继承了基类的数据成员
2.派生类构造函数的形参表不但要包含对派生数据成员初始化的参数,还要包含对基类数据成员初始化的参数
3.派生类构造函数要明确指出分配给基类的参数
派生类名::派生类名(基类所需的形参, 本类新成员所需的形参):基类名1(参数表1),基类名2(参数表2)......
{
本类新成员初始化赋值语句;
}
注意:
1.基类数据成员的初始化有基类的构造函数完成
2.当基类有多个构造函数时,系统会根据参数传递列表自动完成基类构造函数的重载,调用最匹配的基类构造函数初始化继承来的基类成员;若参数表为空,则调用类的无参构造函数(在基类中自定义了构造函数则没有默认构造函数)
2、派生类构造函数的执行顺序
3、派生类构造函数示例
/*由基类: MP3、SD类, 派生出派生类: MP4类*/
#include <iostream>
using namespace std;
class MP3
{
protected:
int mode; //0:顺序播放, 1:随机播放
public:
MP3(int m = 0)
{
mode = m;
cout << "基类MP3的构造函数被调用" << endl;
}
void Display()
{
cout << "MP3:" << mode << endl;
}
};
class SD
{
private:
double size; //内存容量
public:
SD(double s = 8000)
{
size = s;
cout << "基类SD的构造函数被调用" << endl;
}
int getSize()
{
return size;
}
};
class MP4 :public MP3, public SD
{
private:
int type; //O:播放视频, 1:播放音频
public:
MP4(double s, int m, int t) :MP3(m), SD(s)
{
type = t;
cout << "派生类MP4的3参构造函数被调用" << endl;
}
MP4(int t = 0)
{
type = t;
cout << "派生类的默认构造函数被调用" << endl;
}
void Display()
{
cout << "MP4(优先文件类型|默认播放模式):" << type << '|' << mode << endl;
cout << "可用容量:" << getSize() << endl;
}
};
int main()
{
MP4 first_mp4;
first_mp4.Display(); //无参构造
cout << endl;
MP4 second_mp4(4000, 1, 1); 三参构造
second_mp4.Display();
}
4、运行结果
5、派生类的析构函数
在派生过程中,派生类的析构函数也不能继承下来。
派生类析构函数声明方法与没有继承关系的类中的析构函数的声明方法完全相同,只要在函数体中负责把派生类新增的非对象成员的清理工作做好就够了,系统会自己调用基类及对象成员的析构函数来对基类及对象成员进行清理。
但它的执行次序和构造函数恰好完全相反
6、继承VS组合
- 继承和组合都能构建更复杂的类,是实现代码复用的方法
- 从获得其他类的成员的角度来思考,继承和组合在结果上是相似的,但在副本的数量上是有区别的
- 组合是将已有的对象拼合为新对象,是简单的代码复用。新类中可以重复含有已有类的对象,从而多次获得已有类的成员
- 继承是创建一个新类,将其视作现有类的一个 ‘子类型’ ,所以只能获得1次原有类的成员
- 组合比继承更具灵活性和稳定性,在设计时优先使用组合