析构函数是一个特殊的由用户定义的成员函数,如果我们没有创建它,系统会自动帮我们创建一个析构函数。这个是默认析构函数。当该类的对象离开了它的域,或者delete表达式(且其表达式值中的指针必须指向一个带有析构函数的类类型)应用到一个该类的对象的指针上时,析构函数会自动被调用。
注意,析构函数不能被重载。
并不是所有的类都需要析构函数。例如:
class Point3d
{
public:
// ...
private:
float x,y,z ;
};
为了允许用户初始化这三个坐标的内存,构造函数是必需的,但是析构函数呢?在这种情况下,析构函数不是必需的。Point3d类对象没有资源需要被释放,三个坐标成员的存储区在每个类对象声明生命期的开始和结束时,有编译器自动分配和释放。
一般地,如果一个类的数据成员按值存储的,比如Point3d的三个坐标成员,则无需析构函数。并不是每一个类都要求析构函数的,即使我们为该类定义了一个或多个构造函数。析构函数主要被用来存放放弃在类对象的构造函数或生命期中获得的资源,如释放互斥锁或删除有操作符new创建的内存。
无论何时,当在一个函数内删除一个独立的堆对象时,最好用auto_ptr类对象而不是一个实际的指针。对于堆上的类对象尤其应该这样做,否则的话,如果应用delete表达式失败,比如一个异常被抛出的情况下,不但会导致内存泄露,而且析构函数也不会被调用。例如:
#include "Account.h"
Account global("James Joyce") ;
int main()
{
Account local("Anna Livia plurabelle",10000) ;
Account &loc_ref = global ; //这里没有调用构造函数
Account *pact = 0 ; //这里没有调用构造函数
{
Account local_too("Stephen Hero") ;
pact = new Account("Stephen Dedalus") ;
}
delete pact ;
return 0 ;
}
应该改为使用auto_ptr类,程序修改如下:
#include <memory>
#include "Account.h"
Account global("James Joyce") ;
int main()
{
Account local("Anna Livia plurabelle",10000) ;
Account &loc_ref = global ; //这里没有调用构造函数
auto_ptr<Account> pact(new Account("Stephen Dedalus")) ; //使用auto_ptr
{
Account local_too("Stephen Hero") ;
}
//auto_ptr对象在此被销毁
return 0 ;
}