天天看點

c++類和對象之析構函數析構函數二、析構函數和構造函數的調用順序

析構函數

在上一篇文章中,我們介紹了對象的初始化工作。詳情請參考

對象的初始化即構造函數

下面來介紹以下析構函數。

類型:

~類名(){};

析構函數也是一種特殊的成員函數,它的作用與析構函數相反,當對象的生命周期介紹時,會自動調用析構函數。具體來說出現以下四種情況,程式會執行析構函數

1.如果在一個函數中定義了一個對象(假設是局部對象),當這個函數調用結束時,對象應該釋放,在對象釋放前自動執行析構函數。

2.靜态局部對象在函數調用結束時對象并不釋放,是以也不調用析構函數,隻在main函數調用結束或者調用exit函數結束程式時,才調用自動靜态局部對象的析構函數。

3.如果定義了一個全局對象,則在程式的流程離開其作用域時(如main函數調用結束或者調用exit函數結束程式),自動調用該全局對象的析構函數。

4.如果用new運算符動态建立一個對象,當用delete運算符釋放該對象時,先自動調用該對象的析構函數。

注意:

1.構造函數的作用并不是删除對象,而是在撤銷對象占用的記憶體空間之前完成一些清理工作。

2.析構函數沒有任何參數,不能被重載,是以析構函數隻有一個。

3.如果使用者沒有自定義析構函數,c++編譯系統會自動生成一個析構函數,但是它隻是徒有析構函數的名稱和形式,實際上什麼操作都不執行。

二、析構函數和構造函數的調用順序

一般情況下構造函數與析構函數的調用順序相反(這是對同一類存儲類别的對象而言)這是因為存儲在棧上的資料有先進後出的原則,但是并 不是是以的情況都是按這一原則來處理的。在c++中有作用域和存儲類别的概念,這些概念不僅對變量适用,對對象也是适用的,對象可以在不同的作用域中定義,可以有不同的存儲類别,這些都會影響構造與析構的調用順序。

下面歸納以下系統在什麼時候調用構造與析構函數。

1.如果在全局範圍内定義對象,那麼它的構造函數實在本檔案中是以函數(包括main)執行之前調用。但是,如果一個程式包含多個檔案,而不同的檔案中都定義了全局對象,那麼這些對象的構造函數的調用順序時不确定的。當main函數執行結束或者exit退出程式,調用析構函數。

2.如果是局部自動對象(例如在函數内部),則在建立對象時調用其構造函數,如果對象所在的函數被多次調用,則在每次調用構造函數時都要調用構造函數,在函數調用結束,對象釋放時先調用析構函數。

3.如果在函數中定義局部靜态對象,則程式隻在第一次調用此函數定義對象時調用一次構造函數,在調用函數結束時并不釋放,是以也不調用析構函數,隻在main函數執行結束或者exit退出程式,才調用析構函數。

實際上上述構造與析構的調用原則,如果你對全局變量,局部變量,局部靜态變量的了解到位,了解起來就會很簡單,無非時由變量變成了對象而已

繼續閱讀