在前边的学习,我们知道,我们可以把类成员的初始化放在构造函数中,当我们定义类时,自动调用构造函数完成初始化工作;同样的道理,当我们的类对象使用完毕,销毁时,C++同样提供了一个特殊的函数来使我们方便的完成一些收尾工作(比方指针释放等),这个特殊的函数就是析构函数。
-析构函数语法规则: ~className(){}
-析构函数无返回值、无参数,不能重载
#include <iostream>
#include <string>
using namespace std;
class test
{
private:
int *m_p;
public:
test():m_p(NULL) //构造函数中申请堆空间
{
m_p = new int(10);
cout << "test()" << endl;
}
int getValue()
{
return *m_p;
}
~test() //析构函数中释放堆空间
{
delete m_p;
m_p = NULL;
cout << "~test()" << endl;
}
};
int main()
{
{
test t; //定义一个局部对象,放改局部区域执行完毕后对象会自动销毁
cout << "t.getValue() = " << t.getValue() << endl;
}
system("pause");
}
上边的代码中,wo们定义了一个类成员指针,并在构造函数中申请堆空间,对象销毁时在析构函数中释放堆空间
同样,对于堆空间上的对象,前边说过使用new时会构造对象,同时调用构造函数;而对于堆对象的销毁,是在使用delete释放对象时,才销毁堆对象,也就是说堆对象的析构函数,是在使用delete关键字释放对象时才被调用,下边我们对代码做些改动,使得对象为堆对象
#include <iostream>
#include <string>
using namespace std;
class test
{
private:
string m_str;
public:
test(string str):m_str(str)
{
cout << "test() -> " << m_str << endl;
}
~test()
{
cout << "~test() -> " << m_str << endl;
}
};
int main()
{
test *pt1 = new test("pt1"); //定义一个堆对象
test *pt2 = new test("pt2"); //定义一个堆对象
delete pt2; //释放堆对象
delete pt1; //释放堆对象
system("pause");
}
编译输出
从代码中可以看到new的顺序是先pt1再pt2,而delete的顺序是先delete pt2再delete pt1,所以先销毁的就是pt2,即先调用pt2的析构函数。
所以对于堆空间,对象的构造顺序依赖于new关键字,析构顺序依赖于delete关键字
总结
-析构函数是对象销毁时进行清理的特殊函数
-析构函数在对象销毁时自动调用
-析构函数是对象释放系统资源的保障