析构函数是与构造函数相对应的一个函数。构造函数用来对类对象进行初始化,而析构函数则是用来销毁对象。析构函数的函数体往往是空,代表其不进行任何操作。
使用new语句为对象申请空间之后,若在之后的程序中使用delete函数将空间回收,则会自动调用析构函数。在这里,笔者产生了一个疑惑:明明只用delete函数就可以将对象的空间释放,为什么要在设计语言之初要多创造这样一个析构函数?难道仅仅只是为了与构造函数对称?
经过查阅,我找到了舒夜无痕前辈的关于析构函数的学习心得,其中较为严谨的推理并阐述了显式析构函数与隐式析构函数的区别与作用。得出的结论是:显式调用自定义的析构函数与调用普通的成员函数没有区别,仅仅只是将函数体内代码运行一次,而并不销毁对象;只有当对象超出其作用域时,编译器自动隐式调用“编译器自动生成的、函数体与显式相同的的”自定义析构函数,才会进行类对象的销毁。可以通过下面的代码来进行测试。
#include<iostream>
using namespace std;
class Test
{
public:
Test():x(10),y(10){}
~Test()
{
cout<<"deconstructor"<<endl;
cout<<x<<" "<<y<<endl;
}
private:
int x;
int y;
};
int main()
{
Test app;
app.~Test();
return 0;
}
也就是说,如果自定义编写的析构函数不涉及到资源的释放,其实完全可以通过编写另外的一个成员函数来实现这个自定义的函数体。
当构造函数中涉及到资源的申请时,析构函数中也需要显式地进行资源的释放。也就是说如果我在构造函数中使用了new语句,那么在析构函数中就需要delete语句。
回到最上面的问题,为什么需要多一个析构函数来进行delete的工作?可能就是为了形势更加结构化,比较适合通用的编程风格吧。