析构函数
创建类的对象时,会自动调用某个合适的构造函数,同样,当对象被摧毁时,也会自动调用一个析构函数。
析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
对象的摧毁出现在以下两种情况:
- 以某个类作为数据类型的变量超出其作用范围。
- 用delete操作符删除动态分配的对象
与构造函数一样,析构函数也是成员函数。由于析构函数不带参数,因此不能被重载,每个类也只能拥有一个析构函数。
#include<iostream>
#include<string>
using namespace std;
class C{
public:
C() {
name="Null";
cout<<name<<" constructing."<<endl;
}
C(const char* n) {
name = n;
cout<<name<<" constructing."<<endl;
}
~C(){ cout<<name<<" destructing"<<endl; }
private:
string name;
};
int main()
{
C c0("Elen"); // parameterized constructor
{
C c1; //default constructor
C c2("Anny"); // parameterized constructor
}
cout<<endl; // c1 and c2 destructors called
C* ptr=new C(); //default constructor
delete ptr; //destructor for the ptr object
return 0; //c0 destructor called
}
最后输出结果为:
Elen constructing.
Null constructing.
Anny constructing.
Anny destructing
Null destructing
Null constructing.
Null destructing
Elen destructing
- 在这段代码中,首先对象
c0
创建,并伴随着转型构造函数的调用,c0此时生效,直到main
函数退出之前那一刻。 - 接着对象
c1
创建,并伴随着默认构造函数的调用 - 接着对象
c2
创建,并伴随着转型构造函数的调用 - 而由于定义c1和c2的语句位于一个程序块当中,因此在程序块结束之前的一刻,分别调用了c1和c2的析构函数。
- 使用new操作符动态地分配一个对象,并将其地址保存在类型为C*的指针ptr中,由于使用了操作符new,调用默认构造函数以初始化ptr所指对象。
- 使用delete操作符删除ptr所指对象,此时自动调用析构函数。
- 最后main函数在退出之前调用c0的析构函数
可以看出析构函数的调用顺序即位栈的思想,最先创建的则最后调用析构函数。>_<