目录
前言
从之前的学习中我们了解了派生类,中的构造函数和析构函数在类的继承之中的调用顺序,看完以下这篇文章,你大概就会了解派生类中构成函数以及析构函数之间的构造规则
简单的派生类的构造函数和析构函数
首先我们来讲一讲简单的派生类,所谓简单的派生类,就是指他只有一个基类,并且只有一级派生(因为只有直接派生类没有间接派生的一说)并且在派生类中的数据成员是不包含基类的对象及子对象的,下面就来探讨一下在一些简单的派生类中定义构造函数,首先如果基类的构造函数是没有参数或者没有显示的定义构造函数的时候,派生类是一般不能像基类传递参数的,甚至都可以不定义构造函数也行
派生构造函数的一般形式
派生类名(参数总表):基类名(参数表){ 派生类新增数据成员的初始化语句 }
在上面这个例子中,基类的构造函数的参数通常是从带派生类构造函数的总表中得来的,但当然也可以使用常数值,注意的是我们在派生类中可以根据自己的需求来定义属于自己的析构函数,可以用它来进行对派生类中所增加的成员进行清理工作,并且基类的清理工作,我们主要是由基类当中的析构函数负责的,但是由于析构函数不带参数的这一特性,在派生类中要自己判断所定义的析构函数与它对应的基类的析构函数是否无关,最后再执行或者调用派生类的析构函数中,我们的系统才会自动帮我们调用它基类所处的析构函数,对基类的对象进行清理,达到内存的释放
下面我们就来举一个基类中含有参数的构造函数,在派生类中构造函数,析构函数的构造方法的例子
#include<iostream> using namespace std; class B { public: B(int n) { cout << "B类中的构造函数正在使用……" << endl; i = n; } ~B() { cout << "B类中的析构函数正在使用……" << endl; } void Funci() { cout << "i = " << i << endl; } private: int i; }; class A:public B { public: A(int n,int m):B(m){ cout << "A类中的构造函数正在使用……" << endl; j = n; } ~A() { cout << "A类中的析构函数正在使用……" << endl; } void Funcj() { cout << "j = " << j << endl; } private: int j; }; int main() { A obj(50, 60); obj.Funci(); obj.Funcj(); return 0; }
输出结果:
B类中的构造函数正在使用……
A类中的构造函数正在使用……
i = 60
j = 50
A类中的析构函数正在使用……
B类中的析构函数正在使用……
含有子对象的派生类的构造函数
在前面我们介绍过派生类,他们的数据类型都是标准的类型,如int等或者系统提供的类型如string但是实际上派生类中的数据成员还可以是基类的对象,我们把它称之为子对象或者叫对象中的对象
当派生类中含有子对象的时候,它的构造函数的一般形式是:
派生类名(参数总表):基类名(参数表 0),子对象名1(参数(表 1),…,子对象名n(参数表 n){ } 派生类新增成员的初始化语句 }
在定义派生类的对象时,构造函数对它们的调用顺序是如下,先调用基类中的构成函数,把基类中的数据成员进行初始化,然后再调用子对象中的构造函数,将子对象中的数据成员进行初始化,最后才是调用派生类中的构造函数体,对派生类成员中的数据成员进行初始化