参考: http://www.weixueyuan.net/view/6345.html
总结:
析构函数就是用于回收创建对象时所消耗的各种资源。
析构函数的调用顺序与构造函数调用顺序正好是相反的。
类的构造函数负责对象完成初始化及其它相关操作,而析构函数则用于销毁对象时完成相应的资源释放工作。
在创建对象的时候系统会自动调用构造函数,在对象需要被销毁的时候同样系统会自动调用一个函数,这个函数被称之为析构函数。析构函数就是用于回收创建对象时所消耗的各种资源。与构造函数类似,析构函数也是一个成员函数。析构函数与普通成员函数相比,有如下特征:
- 无返回值
- 没有参数,不能被重载,因此一个类也只能含有一个析构函数
- 函数名必须为“~类名”的形式,符号“~”与类名之间可以有空格
在上一节的Array类中,我们没有在类中声明析构函数,在此,我们将其补全如下。
例1:
#include<iostream>
using namespace std; class Array
{
public:
Array(){length = ; num = NULL;};
Array(int * A, int n);
Array(Array &a);
void setnum(int value, int index);
int * getaddress();
void display();
int getlength(){return length;}
~Array();
private:
int length;
int * num;
}; Array::~Array()
{
if(num != NULL)
delete[] num;
cout<<"destructor"<<endl;
} Array::Array(Array & a)
{
if(a.num != NULL)
{
length = a.length;
num = new int[length];
for(int i=; i<length; i++)
num[i] = a.num[i];
}
else
{
length = ;
num = ;
}
} Array::Array(int *A, int n)
{
num = new int[n];
length = n;
for(int i=; i<n; i++)
num[i] = A[i];
} void Array::setnum(int value, int index)
{
if(index < length)
num[index] = value;
else
cout<<"index out of range!"<<endl;
} void Array::display()
{
for(int i=; i<length; i++)
cout<<num[i]<<" ";
cout<<endl;
} int * Array::getaddress()
{
return num;
} int main()
{
int A[] = {,,,,};
Array arr1(A, );
arr1.display();
Array arr2(arr1);
arr2.display();
arr2.setnum(,);
arr1.display();
arr2.display();
cout<<arr1.getaddress()<<" "<<arr2.getaddress()<<endl;
return ;
}
这个例子,现在是一个完整的例子,在这个例子中,我们为其增添了一个析构函数~Array,该函数在main函数退出前被系统自动调用,用于释放num所指向的内存空间。因为有两个对象,因此最终析构函数被调用了两次。
说到析构函数,则其调用顺序则不得不介绍一下了。析构函数与构造函数调用顺序是反转过来的,先调用构造函数的后调用构造函数。我们通过下面的例子来加以说明。
例2:
#include<iostream>
using namespace std; class test
{
public:
test(int i){num = i;cout<<num<<" Constructor"<<endl;}
~test(){cout<<num<<" Destructor"<<endl;}
private:
int num;
}; int main()
{
test t0();
test t1();
test t2();
test t3();
return ;
}
程序运行结果:
0 Constructor
1 Constructor
2 Constructor
3 Constructor
3 Destructor
2 Destructor
1 Destructor
0 Destructor
从这个程序运行不难看出,析构函数的调用顺序与构造函数调用顺序正好是相反的,为了方便记忆,我们可以将之理解为一个栈,先入后出。
类的构造函数负责对象完成初始化及其它相关操作,而析构函数则用于销毁对象时完成相应的资源释放工作。在设计类过程中,我们建议为每个带有成员变量的类设计一个默认构造函数,其它构造函数及析构函数则可以视情况再定。