[英]Why is my exception still being thrown after being caught?
我有以下代碼,其中一個變量正在使用函數調用的結果進行初始化。 這個函數拋出所以我設置了一個try-catch來捕獲異常。 由於某種原因,即使在catch子句運行后,異常仍會出現在屏幕上。
#include <iostream>
#include <stdexcept>
int f() { throw std::invalid_argument("threw"); return 50; }
struct S
{
S()
try : r(f())
{
std::cout << "works";
}
catch(const std::invalid_argument&)
{
std::cout << "fails";
}
int r;
};
int main()
{
S s;
}
顯示異常后,此代碼打印“失敗”:
terminate called after throwing an instance of 'std::invalid_argument' what(): threw
為什么異常仍然被拋出? 我在main中設置了相同的代碼,它可以正常工作:
int main()
{
try { throw std::invalid_argument("blah"); }
catch(const std::invalid_argument&) { }
}
那么為什么它在初始化列表中使用時會失敗呢?
具有函數try塊的構造函數(就像你對S
所擁有的那樣)會自動重新拋出catch
塊捕獲的任何異常。 因此,在后catch
捕獲該異常,它重新拋出它。 此行為與正常的catch
處理程序不同,后者不執行此操作。 我認為基本原理是,如果構造數據成員或基類失敗,則該對象無法構造。 catch
處理程序的目的只是在異常向外傳播之前進行任何額外的清理。
希望這可以幫助!
從C ++ 11標准,15.3 / 15:
如果控制到達構造函數或析構函數的function-try-block的處理程序的末尾,則重新拋出當前處理的異常。
原因在你的問題下的GOTW Jerry鏈接中得到了很好的解釋,但是簡單地說:想象一下如果它沒有重新生成,那么S s;
之后的下一行S s;
盡管它從未完成構造,但可能會嘗試使用s
,並且當s
離開作用域時,構造函數將安排對析構函數調用s
- 可能釋放從未初始化的指針,釋放永不占用的鎖等。
相比之下,如果你讓數據成員默認初始化然后從構造函數體中的try / catch塊分配給它,那么包括基礎和數據成員在內的對象的狀態可能會保持在某種連貫的狀態:它是up作為程序員決定該狀態是否正常 - 即您是否將在構造函數體內使用try / catch塊,並讓后面的成員函數處理潛在的默認構造數據成員。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.