回答
這是一個根本缺陷,使各階層擴展。大多數類別僅僅是不適合被繼承,如果您沒有爲擴展預先設計類,那麼便於這個是沒有意義的。
這只是誤導您的API的用戶誰會將此作爲暗示該類可以有意義地繼承。事實上,這種情況很少出現,並且不會帶來任何好處,或者在最壞的情況下破壞代碼。
一旦你做出一個類繼承,你用它解決你的餘生:你不能改變它的界面,你絕不能打破(隱含!)語義它。本質上,這個班不再是你的。
另一方面,無論如何,繼承是被高估的。除了用於公共接口(純虛擬類)之外,您通常應該更喜歡構造而不是繼承。
另一個更基本的情況下的虛擬析構函數是不希望的是當你有的代碼需要一個工作 - 例如在一個union
使用它時,與C語言代碼的接口或執行時POD-特定的優化時作爲(只有POD是blittable,意味着它們可以非常有效地複製)。 [帽尖安迪]
甲字約性能開銷:存在其中許多小對象被創建的情況下,或者在緊湊循環中創建的對象。在這些情況下,虛擬析構函數的性能開銷可能是一個嚴重錯誤。
具有虛擬功能表的類也是比沒有類更大的,這也會導致不必要的性能影響。
總而言之,沒有令人信服的理由讓析構函數變成虛擬的,並且一些令人信服的理由不是。
我同意所有這一切。但更實際的答案可能是因爲添加虛擬析構函數會破壞結構的POD性,並且有許多應用程序能夠根據其內存內容定義對象,這是設計需求。 – 2012-04-23 23:14:00
@Andy老實說,我甚至沒有想到這一點,這是一個很好的理由,值得自己回答。 – 2012-04-23 23:14:57
@我現在已經添加了這個。 – 2012-04-24 07:07:02
如果你不打算從類繼承計劃(或者如果類不打算繼承),那麼聲明它是虛擬的就沒有意義了。另一方面,如果你想多態地訪問這個類,那麼是的,虛擬析構函數是一件好事。
但是要準確回答你的問題,它不會導致任何「可怕的記憶錯誤」,並且始終將它標記爲虛擬並不能真正傷害你。
但我沒有理由一直使用虛擬析構函數。隨你便。
另外,由Herb發佈的this帶來了一些事情。
不,AFAIK。虛擬析構函數的行爲與非虛擬行爲完全相同(即虛擬和直接調用調用相同的函數),或者您得到未定義的行爲。所以你不能通過將非虛擬析構函數改爲虛擬函數來「做出糟糕的事情」。
但是,它可以暴露由代碼的其他部分引起的錯誤,即。當你不小心覆蓋了對象的虛擬表格指針時。
- 1. 沒有虛擬構造函數但是虛擬析構函數
- 2. C++虛擬析構函數
- 3. CRT虛擬析構函數
- 4. 虛擬析構函數?
- 5. C++虛擬析構函數
- 6. 在.NET中,一個類可以有虛擬構造函數嗎?
- 7. 虛擬函數可以被非虛函數覆蓋嗎?
- 8. 代表應該有一個虛擬析構函數嗎?
- 9. 是否需要定義一個虛擬析構函數?
- 10. 虛擬析構函數 - 有需要時
- 11. 虛擬析構函數如何工作?
- 12. 虛擬析構函數分段錯誤
- 13. 虛擬析構函數:不工作?
- 14. 沒有虛擬方法的虛擬析構函數有什麼危害嗎?
- 15. 當一個類中有虛函數時,隱式生成的析構函數也是虛擬的嗎?
- 16. 如果從析構函數調用純虛函數是UB,爲什麼我們可以使用純虛擬desrtuctors?
- 17. 模板函數的特化可以是虛擬的嗎?
- 18. 類有虛函數和可訪問的非虛擬析構函數
- 19. 當析構函數運行時,是否可以不破壞obj?
- 20. 使用隱形模式時需要虛擬析構函數嗎?
- 21. 在C++中,構造函數和析構函數可以是內聯函數嗎?
- 22. 在虛擬析構函數中調用其他虛擬方法是否安全?
- 23. 爲什麼有可能使析構函數純虛擬
- 24. 以下哪種情況下需要虛擬析構函數?
- 25. 抽象基類的編譯器生成的析構函數是虛擬的嗎?
- 26. 爲什麼QWidget的析構函數不是虛擬的?
- 27. 虛擬析構函數的用法是什麼?
- 28. 升壓「析構函數不是虛擬的」錯誤在MSVC 11
- 29. 爲什麼`boost :: multi_array_ref`的析構函數是非虛擬的?
- 30. 虛擬析構函數是否被繼承?
Konrad採取了這個。 *一個*副作用是它可以消耗大量的二進制大小並增加編譯時間,特別是當沒有一個類的虛擬外行定義時。 – justin 2012-04-23 23:25:08