1,對象的銷毀:
1,生活中的對象都是被初始化后才上市的;
1,為了引入生活中初始化的過程,我們引入了構造函數的概念;
2,生活中的對象被銷毀前會做一些清理工作;
1,生活中手機在回收機構被拆卸,之后將能復用的材料運回工廠再加工利用;
3,C++ 中如何清理需要銷毀的對象?
2,一般而言,需要銷毀的對象都應該做清理,解決方案:
1,為每一個類都提供一個 public 的 free 函數;
2,對象不再需要時立即調用 free 函數進行清理;
3,代碼示例:
1 class Test 2 { 3 Int* p; 4 public: 5 Test() { p = new int; } 6 void free() { delete p; 7 };
3,IntArray 使用分析實例分析:
1,見“C++學習筆記”系列博客中“C++中的深拷貝和淺拷貝構造函數”第9條目中的內容;
2,未有定義析構函數,只是一個 free() 函數,會造成本文中的問題;
4,存在的問題:
1,free 只是一個普通的函數,必須顯示的調用;
2,對象銷毀前沒有做清理,很可能造成資源泄漏;
1,很可能會造成軟件長時間運行的不穩定;
3,C++ 編譯器是否能夠自動調用某個特殊的函數進行對象的清理?
5,析構函數:
1,C++ 的類中可以定義一個特殊的清理函數;
1,這個特殊的清理函數叫做析構函數;
2,析構函數的功能與構造函數相反;
2,定義:~ClassName()(這個特殊的符號是取反的意思)
1,析構函數沒有參數也沒有返回值類型聲明;
1,析構函數是不能重載的,因為重載需要參數列表不同;
2,只剩下函數體可以利用;
2,析構函數在對象銷毀時自動被調用;
6,析構函數使用初探編程實驗:
1 #include <stdio.h> 2 3 class Test 4 { 5 int mi; 6 public: 7 Test(int i) 8 { 9 mi = i; 10 printf("Test(): %d\n", mi); 11 } 12 13 ~Test() 14 { 15 printf("~Test(): %d\n", mi); 16 } 17 }; 18 19 int main() 20 { 21 Test t(1); // 這里被創建,促進構造函數語句的打印,到 return 之前時,局部變量就會被銷毀,此時析構函數被自動調用; 22 23 Test* pt = new Test(2); // 堆空間上定義對象,調用構造函數; 24 25 delete pt; // 刪除指針的同時銷毀堆空間對象,此時會調用析構函數; 26 27 return 0; // 在此語句之前,調用 t 對象析構函數; 28 }
7,IntArray 類的進化編程實驗:
1,將 free() 函數換為析構函數來實現;
2,析構函數只是自動調用並做一些簡單的析構,對於系統資源的析構,還是要手動進行;
8,析構函數的定義准則:
1,當類中自定義了構造函數,並且構造函數中使用了系統資源(如:內存申請,文件打開等),則需要自定義析構函數;
1,自定義了構造函數,多半要自定義析構函數,因為自定義構造函數多半會申請系統資源;
2,析構函數完成的工作有:
1,歸還內存;
2,關閉文件等;
9,小結:
1,析構函數是對象銷毀時進行清理的特殊函數;
2,析構函數在對象銷毀時自動被調用;
3,析構函數是對象釋放系統資源的保障;
1,使編寫的軟件更加穩定;