C++——派生类的构造函数与析构函数 – 作者:Johnson666

1.简单的派生类的构造函数

简单的派生类只有一个基类,而且只有一级派生。
简单派生类的构造函数一般形式为:

派生类构造函数名(总参数列表):基类名(参数列表)
{
    派生类中新增成员变量初始化语句
}

下面通过一个例子来说明
代码:

#include<iostream>
#include<string>
using namespace std;

class Clock
{
public:
	Clock(int h,int m,int s)
	{
		hour = h;
		min = m;
		sec = s;
	}
	void setClock()
	{
		cout << "please enter the present time(hour minute second):";
		cin >> hour >> min >> sec;
	}
	void showTime()
	{
		cout << "hour:" << hour << endl;
		cout << "min:" << min << endl;
		cout << "sec:" << sec << endl;
	}

protected:
	int hour;
	int min;
	int sec;
};

class Date: public Clock
{
public:
	Date(int h,int m,int s,string w): Clock(h,m,s)
	{
		week = w;
	}
	void setDate()
	{
		cout << "please enter the present week:";
		cin >> week;
		setClock();
	}
	void showTime1()
	{
		cout << "week:" << week << endl;
		showTime();
	}

private:
	string week;
};

int main()
{
	Date d(10,40,45,"Thursday");
	d.showTime1();
	d.setDate();
	d.showTime1();
	return 0;
}

结果:
image.png
其中总参数列表包含了基类构造函数所需要的参数和对派生类新增加的成员变量初始化所需的参数。冒号后面的部分表示要调用的基类构造函数及其参数。在构造函数的函数体中,对派生类新增加的成员进行初始化工作,如week = w。

上面的派生类的构造函数可以在类体中只写函数声明,将函数的定义放到类外。
类体中:

Date(int h,int m,int s,string w): Clock(h,m,s);

类外:

Date::Date(int h,int m,int s,string w): Clock(h,m,s)
{
    week = w;
}

派生类的构造函数也可以通过构造函数初始化列表的方式定义。通过初始化列表,不仅可以对构造函数的成员变量初始化,而且可以调用派生类的基类构造函数,实现对基类成员变量的初始化。
比如上面的这个:

Date::Date(int h,int m,int s,string w): Clock(h,m,s)
{
    week = w;
}

可以改写成这个:

Date::Date(int h,int m,int s,string w):Clock(h,m,s),week(w){}

由结果可以看到简单的派生类的构造函数的执行顺序是先调用基类构造函数,再执行派生类构造函数。在派生类对象释放时,执行顺序和构造函数的相反即先执行派生类析构函数,再执行基类析构函数。

2.有子对象的派生类的构造函数

当一个类的对象作为另一个类的成员时,该对象称为该类的子对象。子对象实际上是用对象作为某类的成员变量,该对象可以是基类对象,也可以是其它类的对象。当一个类中出现了子对象成员时,该类的构造函数就要包含对子对象的初始化。

有子对象的派生类的构造函数一般表现形式为:

派生类构造函数名(总参数表列):基类名(参数表列),子对象名(参数表)
{
    派生类中新增成员变量初始化语句
}

例子:
代码:

#include<iostream>
#include<string>
using namespace std;

class Time
{
public:
	Time(int y,int m,int d)
	{
		year = y;
		month = m;
		day = d;
		cout << "子对象Time构造函数被调用" << endl;
	}
	~Time()
	{
		cout << "子对象Time析构函数被调用" << endl;
	}
	void showTime()
	{
		cout << "year:" << year << endl;
		cout << "month:" << month << endl;
		cout << "day:" << day << endl;
	}

private:
	int year;
	int month;
	int day;
};

class Clock
{
public:
	Clock(int h,int mi,int s)
	{
		hour = h;
		min = mi;
		sec = s;
		cout << "基类Clock构造函数被调用" << endl;
	}
	void showTime()
	{
		cout << "hour:" << hour << endl;
		cout << "min:" << min << endl;
		cout << "sec:" << sec << endl;
	}
	~Clock()
	{
		cout << "基类Clock析构函数被调用" << endl;
	}

protected:
	int hour;
	int min;
	int sec;
};

class Date: public Clock
{
public:
	Date(int h,int mi,int s,string w,int y,int m,int d): Clock(h,mi,s),time(y,m,d)
	{
		week = w;
		cout << "派生类Date构造函数被调用" << endl;
	}
	void showTime1()
	{
		time.showTime();
		cout << "week:" << week << endl;
		showTime();
	}
	~Date()
	{
		cout << "派生类Date析构函数被调用" << endl;
	}

private:
	string week;
	Time time;
};

int main()
{
	Date d(13,23,24,"Tuesday",2021,5,25);
	d.showTime1();
	return 0;
}

结果:
image.png
从结果可以看到,对于子对象的派生类的构造函数的执行顺序如下:
(1)先调用基类构造函数,对基类成员变量进行初始化。
(2)再调用子对象构造函数,对子对象成员变量进行初始化。
(3)最后调用派生类构造函数本身(即派生类构造函数的函数体)。
在派生类对象释放时,先执行派生类析构函数,再执行子对象析构函数,最后执行基类析构函数。

来源:freebuf.com 2021-05-25 22:46:44 by: Johnson666

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论