這是一個面試問題。 我告訴他,如果堆棧展開已經在進行中,那麼程序可能會終止。除此之外,如果正確處理異常,您會發現任何問題。 只要處理得當,我就告訴過他。但他對我的迴應並不滿意。C++:從析構函數中拋出異常
1
A
回答
3
那麼,你無法知道是否已經有一個活動異常。如果存在,如果讓另一個異常從析構函數中轉義,則程序將終止。
因此我真的不按照你的說法:
我告訴他沒有,只要它被妥善處理。
你怎麼能「正確地處理」它,而不是讓它從第一個地方逃離析構函數?如果我是面試官,那將是我的下一個問題。
0
如果你從中拋出析構函數,這意味着該異常實際上是離開析構函數。所以妥善處理部分是不可能的:你無法知道它將如何處理。
還有一個額外的細微問題:在很多非平凡的情況下,編寫異常安全的代碼是不可能的(或者至少是非常昂貴的),除非析構函數被假定爲不拋出。如果你的析構函數拋出,你的類的用戶將無法用它編寫好的代碼。例如:除非它所包含的對象的析構函數保證不會拋出,否則不可能爲容器編寫一個異常安全的析構函數。將不會有terminate()
的調用,但容器析構函數會泄漏資源。
0
從析構器投擲使沒有意義。
關於析構函數中唯一可恢復的錯誤類型是在關閉/刷新文件(或類似網絡錯誤等)時發生I/O錯誤。但是從這些情況中恢復是微不足道的。只需報告錯誤並繼續。無論如何你並不需要這個文件,你只是試圖關閉它!放棄你所做的任何事情是很浪費的,因爲你甚至不需要一個文件中的錯誤。
析構函數中可能發生的所有其他類型的失敗,例如無法解鎖互斥鎖或釋放一塊內存,可能無法恢復並且保證可致電terminate()
。
另一方面,由於計算無法繼續,所以在計算中分配資源或未能執行某些I/O操作時發生錯誤,將導致拋出。但是這不應該發生在析構函數中,或者如果它發生了,它應該在析構函數中處理(爲什麼?再次,讓它傳播離開是沒有意義的,這不會阻止錯誤和將放棄計算可以愉快地繼續)。
因此,即使從析構函數中拋出完全安全和明確的,它也不會過多地購買我們。
相關問題
- 1. C++從析構函數中拋出異常
- 2. 從構造函數中拋出異常
- 3. 運行析構函數,當構造函數拋出異常
- 4. 從JNI函數拋出java異常之後調用C++析構函數嗎?
- 5. 從構造函數中拋出異常在C++中
- 6. C++析構函數異常
- 7. 從守衛類析構函數拋出異常導致std :: terminate
- 8. 調用可以在C++中拋出異常的函數的析構函數
- 9. 在MSVC中析構函數拋出異常
- 10. 在析構函數中拋出異常 - 缺點是什麼?
- 11. 在構造函數中拋出的異常:析構函數是否被調用?
- 12. 構造函數和拋出異常
- 13. ServerSocket的構造函數拋出異常
- 14. EJB3構造函數拋出異常?
- 15. Angular2,構造函數DI拋出異常
- 16. 從輔助函數中拋出異常
- 17. 在C++類的構造函數中拋出異常
- 18. new []/delete []並在C++中拋出構造函數/析構函數
- 19. 文件流析構函數可以在C++中拋出異常嗎?
- 20. 當我在C++析構函數中拋出異常時會發生什麼?
- 21. 空std :: list當析構函數被調用時拋出異常
- 22. 如何處理拋出異常的文件析構函數?
- 23. 如何從枚舉構造函數中拋出異常?
- 24. C++析構函數在拋出特定異常時跳過工作的方式?
- 25. C++異常拋出
- 26. C#拋出異常
- 27. C#拋出異常
- 28. 在C++中拋出異常異常
- 29. 升壓正則表達式異常從構造函數拋出* {
- 30. 從繼承函數拋出異常而不拋出
預期的答案可能是:「不要這樣做」。在這裏閱讀更多:http://stackoverflow.com/questions/130117/throwing-exceptions-out-of-a-destructor – Misch 2013-04-11 14:24:08
如果你的類被破壞,因爲拋出異常,並且棧正在展開,並且析構函數拋出一個例外,該程序將立即終止。沒有辦法來捕捉或處理這樣的例外。 – Wug 2013-04-11 14:29:06
當你嘗試建立回答你所做的事情的理由時,你可能應該已經澄清了你的回答,相對於在析構函數中拋出一個析構函數與*的異常。 – WhozCraig 2013-04-11 14:34:57