在析構函數中檢測到它是在堆棧展開期間運行的時候,由於引發了異常而不是觸發析構函數的範圍的正常退出,C++中的一個好方法是什麼?我想知道這樣我可以創建一個類,它有一些總是在正常退出時運行的清理代碼,但在發生異常時會跳過。檢測由於異常被拋出而導致析構函數何時運行?
13
A
回答
16
std::uncaught_exception()
(在<exception>
定義)會告訴你,在你的析構函數,如果它被稱爲是因爲一個例外:
class A
{
public:
~A()
{
if (std::uncaught_exception()) {
// Called because of an exception
} else {
// No exception
}
}
};
+0
不錯,我從來不知道這個存在! :-) –
+0
不如您想象的那麼好 - 請參閱我的帖子中的鏈接文章。 – Simon
0
這是我能想到的一個辦法,但似乎笨拙:
{
myCleanupClass unwindAction;
try {
// do some work which may throw exception.
} catch (...) {
unwindAction.disableDestructorWork();
throw;
}
}
1
不要那樣做,除非你有充分的理由。堆棧展開是一種語言功能,try
塊內的所有自動對象都將被強制釋放,以便它們內部的資源有機會釋放。
您想在堆棧展開期間跳過清除,這繞開了它的初衷。而且你會冒着泄漏資源的風險。
例
class CDBConnection
{
public:
CDBConnection()
{
m_db.open();
}
~CDBConnection()
{
if (!std::uncaught_exception())
m_db.close();
// if this is called during a stack unwinding,
// your DB connection will not be closed for sure.
// That's a resource leakage.
}
//..
private:
DB m_db;
};
void main()
{
//..
try
{
// code that may throw
CDBConnection db;
//..
}
catch(const CDBException& exp)
{
// properly handle the exception
}
}
4
可能this文章將幫助你。本文將向您展示std :: uncaught_exception()的問題,幷包含如何處理析構函數中的異常的建議。
相關問題
- 1. 運行析構函數,當構造函數拋出異常
- 2. 從守衛類析構函數拋出異常導致std :: terminate
- 3. 空std :: list當析構函數被調用時拋出異常
- 4. 運行時異常可以被拋出?
- 5. 構造函數拋出運行時異常
- 6. 構造函數可以拋出運行時異常嗎?
- 7. System.ServiceModel.ServiceHost.AddServiceEndpoint構造函數導致異常拋出
- 8. 在構造函數中拋出的異常:析構函數是否被調用?
- 9. 通用類構造函數在運行時拋出類拋出異常錯誤
- 10. A4J:支持重新解析導致NumberFormatException異常被拋出
- 11. 當使用mockito拋出運行時異常時,測試自定義異常是否被拋出
- 12. Hadoop測試BenchmarkThroughput由於mapred.temp.dir而導致NullPointerException異常
- 13. 如何處理拋出異常的文件析構函數?
- 14. 構造函數和拋出異常
- 15. ServerSocket的構造函數拋出異常
- 16. 從構造函數中拋出異常
- 17. EJB3構造函數拋出異常?
- 18. Angular2,構造函數DI拋出異常
- 19. 我應該如何記錄不是由某個方法/構造函數拋出的異常,而是可能被另一個被調用的異常拋出?
- 20. 當拋出異常時,析構函數沒有執行(沒有堆棧展開)
- 21. 由於構造函數而解析類型時出錯?
- 22. 如何檢測CLR拋出的異常?
- 23. fwrite函數在酒中運行時導致異常
- 24. 瞭解由構造函數拋出的異常
- 25. 無法捕獲由std :: thread構造函數拋出的異常
- 26. 由WCF服務構造函數拋出的日誌異常?
- 27. java拋出運行時異常
- 28. 拋出運行時異常故意
- 29. Android Visualizer類拋出運行時異常
- 30. 異常:拋出java.lang.ClassNotFoundException:javax.servlet.http.HttpServletRequest運行時的Servlet
有趣的問題!我很想說它不能完成,因爲對象並不真正知道異常處於活動狀態,它們只是在異常展開堆棧時超出範圍,就好像它們超出了其他範圍範圍。如果有什麼,你需要一些特定於平臺的「黑客」... –
好奇你爲什麼要在堆棧展開期間避免清理? –
@Eric Z:我曾想過將它用於自動堆棧記錄。 'Log xxx(「funcA - 」,arg1,arg2,arg3);',但是對這些函數進行測試是很乏味的。 –