對于以下代碼:
#include <iostream>
結構 Str
{
Str() { throw 100; }; ; ; 100?
};
class Cla
{
public:
Cla()
try : m_mem( ) { }
catch(...)
{
std::cout << "Catch block is called"<< std::endl;
}
private:
Str m_mem;
};
int main()
{
Cla obj;
}
我試圖在catch塊中捕獲例外。但是在catch塊運行后,系統仍然呼叫std::terminate來終止程式。我沒有在catch塊中重新拋出例外,你能告訴我為什么系統會崩潰嗎?謝謝!
這里有一個在編譯器資源管理器上的測驗。https://godbolt.org/z/74sTcxrY4
uj5u.com熱心網友回復:
你在自相矛盾。
你在自相矛盾。
我試圖在catch塊中捕獲例外。但是在抓取塊運行后
如果運行了 catch 塊,你成功了從初始化器串列中捕獲了例外。你只是對接下來發生的事情感到驚訝而已。
首先,讓我們思考一下當建構式拋出時發生了什么:物件沒有被構造。對嗎?建構式從未完成對它的設定,所以你不能用它來做任何事情。
首先,讓我們想想當建構式拋出時發生了什么:物件沒有被構造。
int main(){
Cla obj; ///成員子物件構造器拋出,但我們抓住了它!{
obj.print(); //但是我們仍然不能在這里使用,因為建構式從未完成。
}
因此,讓你在這里吞下這個例外并沒有什么意義。你不能處理它,因為你不能回去重新構造你的成員和基類子物件。如果你沒有一個正確構建的物件,C 處理這個問題的唯一方法是解除塊范圍,否則該物件將被假定為......嗯,一個真正的物件。
因此,根據檔案:
建構式嘗試塊中的每個 catch-clause 都必須以拋出一個例外來結束。如果控制元件到達此類處理程式的末尾,當前的例外將自動被重新拋出,就像拋出;一樣。在建構式嘗試塊的任何 catch 子句中都不允許出現回傳陳述句。
......在標準中也是如此(draft)
如果控制到達建構式或解構式的function-try-block處理程式的末端,當前處理的例外將被重新拋出。 否則,從函式嘗試塊的處理程式的復合陳述句的末端流走,相當于從該函式的復合陳述句的末端流走(見 [stmt.return])
uj5u.com熱心網友回復:
在建構式的捕獲塊中,沒有辦法吞噬一個例外。它必然會拋出一些東西,如果控制到達捕獲塊的末端,就會拋出捕獲的例外。唯一的方法是std::terminate或者在這之前終止。
來自cppreference:
建構式嘗試塊中的每個 catch-clause 都必須以拋出一個例外來結束。如果控制元件到達這種處理程式的末尾,當前的例外將自動被重新拋出,就像拋出;一樣。在建構式嘗試塊的任何 catch 子句中都不允許出現回傳陳述句。
這是有意為之的,也是有益的。從一個沒有完成的建構式中回傳是沒有意義的,這將使一個物件可以被訪問,盡管實際上沒有被創建。
這樣的 catch 塊可用于記錄錯誤、釋放資源(如果你沒有使用 RAII)以及執行其他類似的清理作業。但是它不能阻止例外的傳播。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/331852.html
標籤:
上一篇:在提交前通過jquery驗證表單
