轉自:http://c.biancheng.net/cpp/biancheng/view/196.html
析構函數(destructor)也是一個特殊的成員函數,它的作用與構造函數相反,它的名字是類名的前面加一個“~”符號。
在C++中“~”是位取反運算符,從這點也可以想到,析構函數是與構造函數作用相反的函數。當對象的生命期結束時,會自動執行析構函數。
具體地說如果出現以下幾種情況,程序就會執行析構函數:
- 如果在一個函數中定義了一個對象(它是自動局部對象),當這個函數被調用結束時,對象應該釋放,在對象釋放前自動執行析構函數。
- static局部對象在函數調用結束時對象並不釋放,因此也不調用析構函數,只在main函數結束或調用exit函數結束程序時,才調用static局部對象的析構函數。
- 如果定義了一個全局對象,則在程序的流程離開其作用域時(如main函數結束或調用exit函數) 時,調用該全局對象的析構函數。
- 如果用new運算符動態地建立了一個對象,當用delete運算符釋放該對象時,先調用該對象的析構函數。
析構函數的作用並不是刪除對象,而是在撤銷對象佔用的內存之前完成一些清理工作,使這部分內存可以被程序分配給新對象使用。程序設計者事先設計好析構函數,以完成所需的功能,只要對象的生命期結束,程序就自動執行析構函數來完成這些工作。
注意:析構函數不返回任何值,沒有函數類型,也沒有函數參數。因此它不能被重載。一個類可以有多個構造函數,但只能有一個析構函數。
實際上,析構函數的作用並不僅限於釋放資源方面,它還可以被用來執行“用戶希望在最後一次使用對象之後所執行的任何操作”,例如輸出有關的信息。這裏說的用戶是指類的設計者,因爲,析構函數是在聲明類的時候定義的。也就是說,析構函數可以完成類的設計者所指定的任何操作。
一般情況下,類的設計者應當在聲明類的同時定義析構函數,以指定如何完成“清理”的工作。如果用戶沒有定義析構函數,C++編譯系統會自動生成一個析構函數,但它只是徒有析構函數的名稱和形式,實際上什麼操作都不進行。想讓析構函數完成任何工作,都必須在定義的析構函數中指定。
【例9.5】包含構造函數和析構函數的C++程序。
- #include<string>
- #include<iostream>
- using namespace std;
- class Student //聲明Student類
- {
- public :
- Student(int n,string nam,char s ) //定義構造函數
- {
- num=n;
- name=nam;
- sex=s;
- cout<<"Constructor called."<<endl; //輸出有關信息
- }
- ~Student( ) //定義析構函數
- {
- cout<<"Destructor called. The num is "<<num<<"."<<endl;
- } //輸出有關信息
- void display( ) //定義成員函數
- {
- cout<<"num: "<<num<<endl;
- cout<<"name: "<<name<<endl;
- cout<<"sex: "<<sex<<endl<<endl;
- }
- private :
- int num;
- string name;
- char sex;
- };
- int main( )
- {
- Student stud1(10010,"Wang_li",'f'); //建立對象stud1
- stud1.display( ); //輸出學生1的數據
- Student stud2(10011,"Zhang_fun",'m'); //定義對象stud2
- stud2.display( ); //輸出學生2的數據
- return 0;
- }
Constructor called. (執行stud1的構造函數)
num: 10010 (執行stud1的display函數)
name:Wang_li
sex: f
Constructor called. (執行stud2的構造函數)
num: 10011 (執行stud2的display函數)
name:Zhang_fun
sex:m
Destructor called. The num is 10011. (執行stud2的析構函數)
Destructor called. The num is 10010. (執行stud1的析構函數)