(二)析构函数
析构函数的作用:完成一个清理工作,但并不是删除对象,而是释放对象占用的内存。比如释放从heap中分配的内存。
析构函数的使用:
① 与构造函数的作用相反,在类名前加 "~"符号。比如~rectangle;
②不返回任何值,没有函数类型,也没有函数参数,由于无函数参数,则不能被重载,一个类只能有一个析构函数,但可以有多个构造函数。
③一般情况下,在声明类的同时就定义析构函数。
④系统会自动执行析构函数的工作。
⑤ 如果当用户没有显式定义析构函数时, 编译器同样会为对象生成一个默认的析构函数, 但默认生成的析构函数只能释放类的普通数据成员所占用的 间, 无法释放通过 new 等进行申请的空间, 因此有时我们需要自己显式的定义析构函数对这些申请的空间进行释放, 避免造成内存泄露。
⑥如果用new申请动态内存建立一个对象,当用delete释放时,先调用该对象的析构函数
看一个简例
#include<iostream>
using namespace std;
class rectangle
{
private:
int len;
int wid;
public:
rectangle(int a,int b):len(a),wid(b)//定义有参数的构造函数
{
cout<<"构造函数"<<endl;
}
~rectangle()//定义析构函数
{
cout<<"析构函数"<<endl;
}
void show()//定义成员函数
{
cout<<"长"<<":"<<len<<endl;
cout<<"宽"<<":"<<wid<<endl;
}
};
int main()
{
rectangle A(4,5);//建立对象A
A.show();
rectangle B(6,8);//建立对象B
B.show();
return 0;
}
运行结果
构造函数
长:4
宽:5
构造函数
长:6
宽:8
析构函数
析构函数
最后的两行“析构函数”分别是属于哪个对象的呢? 试验一下,将以下部分稍作改动
~rectangle()//定义析构函数
{
cout<<"析构函数"<<":"<<len<<endl;
}
运行结果变为
构造函数
长:4
宽:5
构造函数
长:6
宽:8
析构函数:6
析构函数:4
可知:先构造的后析构,后构造的先析构。原因即:“~”这个符号是 取反
另外如果是指针在new之后,需要手动delete释放资源。在较大型的工程当中,资源的释放很重要,因为涉及的数据量比较多,稍有不慎,就会造成资源的浪费和泄露之类的问题
#include<iostream>
using namespace std;
class rectangle
{
private:
int len;
int wid;
public:
rectangle(int a,int b):len(a),wid(b)//定义有参数的构造函数
{
cout<<"构造函数"<<endl;
}
~rectangle()//定义析构函数
{
cout<<"析构函数"<<":"<<len<<endl;
}
void show()//定义成员函数
{
cout<<"长"<<":"<<len<<endl;
cout<<"宽"<<":"<<wid<<endl;
}
int getx()
{
return len;
}
int gety()
{
return wid;
}
};
int main()
{
rectangle A(4,5);//建立对象A
A.show();
rectangle B(6,8);//建立对象B
B.show();
rectangle *C;
C= new rectangle(8,9);
cout<<"长"<<":"<<C->getx()<<endl;
cout<<"宽"<<":"<<C->gety()<<endl;
return 0;
}
运行结果 可以发现动态申请后的并没有输出析构函数
构造函数
长:4
宽:5
构造函数
长:6
宽:8
构造函数
长:8
宽:9
析构函数:6
析构函数:4
则需要手动delete
C= new rectangle(8,9);
cout<<"长"<<":"<<C->getx()<<endl;
cout<<"宽"<<":"<<C->gety()<<endl;
delete C;///手动释放
运行结果
构造函数
长:4
宽:5
构造函数
长:6
宽:8
构造函数
长:8
宽:9
析构函数:8
析构函数:6
析构函数:4
嗯嗯,就这些!!