我運行了一個示例程序,確實調用了堆棧分配對象的析構函數,但這是由標準保證的嗎?在C++中拋出後調用析構函數嗎?
回答
是,它是保證(提供的異常被捕獲),下降到其中析構函數調用的順序:
C++ 11 15.2構造和析構[except.ctor]
1控件從throw表達式傳遞到處理函數時,自從try塊被輸入後構造的所有自動對象都會調用析構函數。 自動對象按照其構造完成 的相反順序銷燬。
此外,如果異常對象施工過程中引發,所述部分構造的對象的子對象,保證被正確地破壞:
2的任何存儲持續時間,其初始化或 破壞的目的被一個異常終止,將會爲其所有完全構造的子對象(不包括 聯合類類的變體成員)執行析構函數 ,也就是說,對於主體構造函數(12.6.2)已完成執行的 子對象和 析構函數尚未開始執行。同樣,如果對象的非委託構造函數已完成執行,並且此對象的委託構造函數退出且出現異常,則將調用對象的析構函數。如果對象是以 新表達式分配的,則會調用匹配的釋放函數(3.7.4.2,5.3.4, 12.5)以釋放對象佔用的存儲空間(如果有)。
這整個過程被稱爲「堆棧展開」:
3要求自動對象析構函數的方法,構造從try塊到一拋表達的路徑上 被稱爲「堆 展開「。如果在堆棧展開過程中調用的析構函數以 作爲異常退出,則調用std :: terminate(15.5.1)。
堆疊展開形成了廣泛使用的技術Resource Acquisition Is Initialization (RAII)的基礎。
請注意,如果未捕獲到異常,堆棧展開不一定會完成。在這種情況下,堆棧展開是否完成取決於實現。但是,無論堆疊展開是否完成,在這種情況下,您都可以保證最終致電std::terminate
。
C++ 11 15.5.1的std ::終止()函數[except.terminate]
2…在沒有找到匹配處理程序的情況下, 它是實現定義的,無論在調用
std::terminate()
之前堆棧是否展開。
注意:關於構造中斷的對象。對象本身並沒有被銷燬(它從來沒有真正存在過),保證的是到目前爲止完全構造的子部件(基類,屬性)將以相反的順序銷燬。 –
爲未捕獲的異常添加了有關堆棧展開(或不展開)的信息。 –
- 1. 從JNI函數拋出java異常之後調用C++析構函數嗎?
- 2. new []/delete []並在C++中拋出構造函數/析構函數
- 3. 調用可以在C++中拋出異常的函數的析構函數
- 4. 如果對象在構造函數中拋出異常,基類的析構函數會調用嗎?
- 5. 文件流析構函數可以在C++中拋出異常嗎?
- 6. 成功調用析構函數或調用empy析構函數後出現Seg錯誤。 C++
- 7. C++:從析構函數中拋出異常
- 8. C++從析構函數中拋出異常
- 9. C#:'拋出'退出當前函數嗎?
- 10. 拋出異常然後調用構造函數?
- 11. Visual C#中沒有析構函數嗎?
- 12. 正在從析構函數調用非成員函數嗎?
- 13. C++析構函數沒有被調用?
- 14. C++析構函數和調用順序
- 15. C++析構函數早期調用
- 16. C++析構函數太早調用
- 17. 在C++中,構造函數和析構函數可以是內聯函數嗎?
- 18. 複製構造函數調用析構函數C++
- 19. C++ - 當矢量持有對象時調用析構函數嗎?
- 20. 在構造函數中拋出ArgumentNullException?
- 21. 在c#中析構函數的使用?
- 22. 我可以在Window析構函數(finalizer)中調用MessageBox.Show()嗎?
- 23. 當我在C++析構函數中拋出異常時會發生什麼?
- 24. 構造函數可以在C++中調用另一個構造函數嗎?
- 25. 從構造函數中拋出異常在C++中
- 26. C++中構造函數的調用不等於C++中析構函數的調用次數
- 27. 析構函數在C++
- 28. 析構函數LinkedListelement在C++
- 29. C++中的析構函數
- 30. C++中的析構函數
當然可以。 [RAII](http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization)是C++中最重要的成語之一,取決於此。 – Jon
是的,這是異常處理的重點。 –