【c++】类的构造函数和析构函数

天大地大妈咪最大 提交于 2019-12-07 07:37:42

【c++】类的构造函数和析构函数

            一.构造函数

            二.构造函数的重载

            三.析构函数

参考:

《c++从入门到精通》 人民邮电出版社

 

一.构造函数

    构造函数是和类名相同的一个函数,它的作用是实现对象的初始化。当对象被创建时,构造函数自动被调用。 

    特点:

            1.没有类型

            2.没有返回值(也不用写void)

            3.名字与类名相同

            4.可重载!

    作用:完成类的对象的初始化

Cdate d; //定义对象d

    注意:当对象d被创建时,会自动调用构造函数 d.Cdate()。

    当类中未定义构造函数时,编译器会自动假设存在以下两个默认构造函数:(此构造函数什么都不做,就是个形式)。如果作者自己定义了构造函数,则默认的构造函数不会存在。

//默认构造函数一
Cdate::Cdate()
{
}

//默认构造函数二
Cdate::Cdate(const Cdate& a)
{
}

编程实例:

//构造函数.cpp
#include<iostream> 
using namespace std;

class Cdate
{
	public:
		Cdate(int ,int ,int ); //构造函数 
		void print();  //成员函数 
	private:
		int year,month,day;  //成员数据 
};

// 构造函数的实现 
Cdate::Cdate(int x,int y,int z) //构造函数 
{
	year=x;
	month=y;
	day=z;
}
// 成员函数的实现 
void Cdate:: print()
{
	cout<<year<<" "<<month<<" "<<day<<endl; 
}


int main()
{
	Cdate d(2018,5,6);
	d.print(); 
	return 0;
}

运行结果:

 

二.构造函数的重载

    像其他普通函数一样,构造函数也可以被多次重载(只要各构造函数有不同的参数类型和个数)。

Cdate();  //构造函数 不带参数
Cdate(int ,int ,int ); //构造函数  带参数

    重载时,编译器会自动调用与要求的参数个数和类型相同的那个构造函数。

 

编程实例:

//构造函数重载.cpp
#include<iostream> 
using namespace std;

class Cdate
{
	public:
		Cdate();  //构造函数 不带参数 
		Cdate(int ,int ,int ); //构造函数  带参数 
		void print();  //成员函数 
	private:
		int year,month,day;  //成员数据 
};

// 构造函数的实现 
Cdate::Cdate() //构造函数 
{
	year=1999;
	month=7;
	day=1;
}

// 构造函数的实现 
Cdate::Cdate(int x,int y,int z) //构造函数 
{
	year=x;
	month=y;
	day=z;
}
// 成员函数的实现 
void Cdate:: print()
{
	cout<<year<<" "<<month<<" "<<day<<endl; 
}


int main()
{
	
	Cdate d1(2018,5,6);
	cout<<"d1:" ;
	d1.print();
	
	
	Cdate d2;
	cout<<"d2:"; 
	d2.print();
	return 0;
}

运行结果:

    

 

三.析构函数

    我们已经知道构造函数是在创建对象时,对其进行初始化。而析构函数与其相反,是在对象被删除前象由系统自动执行它做清理工作

    作为一个类,可能有多个对象,每个对象生命结束时都要调用析构函数,且每个对象调用一次。

特点:

            1.无类型

            2.无返回值

            3.名字与类名相同

            4.不带参数,不可重载,析构函数只有一个!

            5.析构函数前~ (取反符,表示逆构造函数)

作用:在对象被删除前做清理工作。

注意:对象的析构函数在对象被销毁前被调用,对象何时销毁也与其作用域相关。

    例如,全局对象是在程序运行结束时销毁;

              自动对象是在离开其作用域时销毁;

              而动态对象是在使用delete运算符时销毁。

        析构函数特别适用于当一个对象被动态分配内存空间,而在对象被销毁前希望释放它所占用的内存空间的时候。我们不会忽略初始化的重要性,却常常忽略清除的重要性,然而对销毁变量的内存清理是非常重要的。

        例如,我们在中申请了一些内存,如果没有用完就释放,会造成内存泄露,会导致应用程序运行效率降低,甚至崩溃,不可掉以轻心。

        而在c++中提供有析构函数,可以保证对象清除工作自动执行。

编程实例:

//析构函数.cpp
#include<iostream> 
using namespace std;

class Cdate
{
	public:
		Cdate(int ,int ,int ); //构造函数  带参数 
		~Cdate();  //析构函数 
		void print();  //成员函数 
	private:
		int year,month,day;  //成员数据 
};


// 构造函数的定义 
Cdate::Cdate(int x,int y,int z) //构造函数 
{
	year=x;
	month=y;
	day=z;
	cout<<"实现构造函数"<<endl; 
}
// 析构函数的定义 
Cdate::~Cdate() //析构函数 
{
	
	cout<<"析构函数释放变量占用的内存资源"<<endl; 
}


// 成员函数的实现 
void Cdate:: print()
{
	cout<<year<<" "<<month<<" "<<day<<endl; 
}


int main()
{
	
	Cdate d1(2018,5,6);
	cout<<"d1:" ;
	d1.print();
	
	return 0;
}

运行结果:

        

分析一下构造函数和析构函数的工作过程:

    Cdate d1(2018,5,6); //定义对象

    首先是创建对象时先自动调用构造函数进行初始化

    最终在对象被删除前执行析构函数,实现变量占用内存的清理工作


析构函数调用次序的编程实例:使得这一过程更清楚。

//析构函数.cpp
#include<iostream> 
using namespace std;

class Cdate
{
	public:
		Cdate(int  ); //构造函数  带参数 
		~Cdate();  //析构函数 
		void print();  //成员函数 
	private:
		int num;  //成员数据 
};


// 构造函数的定义 
Cdate::Cdate(int x) //构造函数 
{
	num=x;
	cout<<num<<":";
	cout<<"构造函数被调用"<<endl; 
}
// 析构函数的定义 
Cdate::~Cdate() //析构函数 
{
    cout<<num<<":";
	cout<<"析构函数被调用"<<endl; 
}


// 成员函数的实现 
void Cdate:: print()
{
	cout<<num<<endl; 
}


int main()
{
	cout<<"进入main()函数:"<<endl;
	
	Cdate d1(1);
	Cdate d2(2);
	Cdate d3(3);
	
	cout<<"main()函数运行中:"<<endl;
	cout<<"退出main()函数"<<endl;
	return 0;
}

运行结果:

            

本实例表明,析构与构造的调用次序相反,即最先构造的最后被析构,最后构造的最先被析构。

 -------------------------------------------         END      -------------------------------------

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!