C++析構函數(shù)詳解

創(chuàng)建對象時系統(tǒng)會自動調(diào)用構造函數(shù)進行初始化工作,同樣,銷毀對象時系統(tǒng)也會自動調(diào)用一個函數(shù)來進行清理工作,例如釋放分配的內(nèi)存、關閉打開的文件等,這個函數(shù)就是析構函數(shù)。
析構函數(shù)(Destructor)也是一種特殊的成員函數(shù),沒有返回值,不需要程序員顯式調(diào)用(程序員也沒法顯式調(diào)用),而是在銷毀對象時自動執(zhí)行。構造函數(shù)的名字和類名相同,而析構函數(shù)的名字是在類名前面加一個~
符號。
注意:析構函數(shù)沒有參數(shù),不能被重載,因此一個類只能有一個析構函數(shù)。如果用戶沒有定義,編譯器會自動生成一個默認的析構函數(shù)。
上節(jié)我們定義了一個 VLA 類來模擬變長數(shù)組,它使用一個構造函數(shù)為數(shù)組分配內(nèi)存,這些內(nèi)存在數(shù)組被銷毀后不會自動釋放,所以非常有必要再添加一個析構函數(shù),專門用來釋放已經(jīng)分配的內(nèi)存。請看下面的完整示例:
Input array length: 5
Input 5 numbers: 99 23 45 10 100
Elements: 99, 23, 45, 10, 100
~VLA()
就是 VLA 類的析構函數(shù),它的唯一作用就是在刪除對象(第 53 行代碼)后釋放已經(jīng)分配的內(nèi)存。函數(shù)名是標識符的一種,原則上標識符的命名中不允許出現(xiàn)
~
符號,在析構函數(shù)的名字中出現(xiàn)的~
可以認為是一種特殊情況,目的是為了和構造函數(shù)的名字加以對比和區(qū)分。注意:at() 函數(shù)只在類的內(nèi)部使用,所以將它聲明為 private 屬性;m_len 變量不允許修改,所以用 const 進行了限制,這樣就只能使用初始化列表來進行賦值。
C++?中的 new 和 delete 分別用來分配和釋放內(nèi)存,它們與C語言中 malloc()、free() 最大的一個不同之處在于:用 new 分配內(nèi)存時會調(diào)用構造函數(shù),用 delete 釋放內(nèi)存時會調(diào)用析構函數(shù)。構造函數(shù)和析構函數(shù)對于類來說是不可或缺的,所以在C++中我們非常鼓勵使用 new 和 delete。
析構函數(shù)的執(zhí)行時機
析構函數(shù)在對象被銷毀時調(diào)用,而對象的銷毀時機與它所在的內(nèi)存區(qū)域有關。不了解內(nèi)存分區(qū)的讀者請閱讀《C語言內(nèi)存精講》專題。
在所有函數(shù)之外創(chuàng)建的對象是全局對象,它和全局變量類似,位于內(nèi)存分區(qū)中的全局數(shù)據(jù)區(qū),程序在結束執(zhí)行時會調(diào)用這些對象的析構函數(shù)。
在函數(shù)內(nèi)部創(chuàng)建的對象是局部對象,它和局部變量類似,位于棧區(qū),函數(shù)執(zhí)行結束時會調(diào)用這些對象的析構函數(shù)。
new 創(chuàng)建的對象位于堆區(qū),通過 delete 刪除時才會調(diào)用析構函數(shù);如果沒有 delete,析構函數(shù)就不會被執(zhí)行。
下面的例子演示了析構函數(shù)的執(zhí)行。
1
main
3
2