【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 -------------------------------------
来源:CSDN
作者:大姨妈V
链接:https://blog.csdn.net/u012679707/article/details/80217265