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