c++ map 析构函数_说说C++的虚析构函数
首先看一段示例代碼:
class上面代碼中 class AX 的析構函數不會被調用,如果在 AX 析構函數中需要進行一些資源釋放工作(一般都是如此)則這些工作不會被執行。解決的方法就是將基類析構函數聲明為虛函數,如下:
class看起來很完美對不對。然而本文的目的并不是介紹如何使用虛析構函數,恰恰相反,本文想表達的觀點是:當需要用虛析構解決問題時,通常意味著代碼設計出問題了。
上面一段代碼是所謂的“示例代碼”,很少有示例代碼的代碼邏輯能直接在工程中使用,因為它們通常都太簡單了,而實際工程通常都是復雜的,甚至有一些完全無法在工程中使用。這也是為什么很多知識學起來似乎很簡單用起來卻很難的原因。
接下來我們按照盡量貼近實際工程的方式修改上述代碼:
// A.h代碼被分開到了三個文件中,Method() 中的代碼實際使用的是 class A,并不需要了解 class AX 的定義,所以我們引入工廠模式來消除 method() 函數對 class AX 的依賴:
// A.h終于有點工業強度代碼的樣子了。看起來似乎沒什么問題,對嗎?那接著來。
有了工廠模式,可以玩很多花活兒了,比如如果 class AX 的對象會被頻繁創建和銷毀影響性能,所以我們引入內存池分配內存,或者建個對象池對使用完畢的對象銷毀再利用等等。AFactory::CreateAX 可能被改成下面的樣子:
A發現什么了嗎?函數 Method() 中原本正確的代碼現在變成錯誤代碼了。我們常常強調代碼的健壯性,什么叫健壯的代碼不太好描述,什么叫脆弱的代碼看這里就知道了:我們修改了某個位置的代碼,然后在千里之外的其他地方引發了BUG。
更嚴重的是,不僅僅是修改內存分配方式這種明顯的行為,其他諸如升級編譯器版本甚至修改編譯參數都可能產生同樣的效果。在大規模的項目中,class A 和 Method() 的代碼分屬不同的開發人員、甚至不同團隊、不同公司是很平常的事情,這種情況下如此脆弱的代碼非常難以維護。
本質上是因為虛析構函數假定派生類對象必須使用 new 創建,使得調用代碼和實現代碼多出了一條隱藏的強耦合關系。更好的處理方式是如果一個類需要被繼承,那么直接把其析構函數聲明為 protected,禁止調用代碼使用 delete 釋放基類指針。可以在創建對象時使用智能指針,這樣調用代碼就不必關心對象如何創建和如何釋放的問題。
虛析構的另一個問題是會改變虛函數表的結構,導致跨語言使用虛函數表時出現兼容性問題,情況比較少見,這里不再展開細說。
只有在設計上需要在基類中處理派生類釋放時才必須使用虛析構(比如以繼承實現的方式實現侵入式引用計數),其他情況都可以繞開并且比使用虛析構帶來更好的代碼健壯性。
所以,如果發現需要使用虛析構解決問題,意味著代碼該重構了。
總結
以上是生活随笔為你收集整理的c++ map 析构函数_说说C++的虚析构函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么跳过bios密码 跳过BIOS密码的
- 下一篇: 机械师f117蓝屏没U盘怎么办 机械师f