簡體   English   中英

為什么在異常處理c ++中在catch之前需要一個try塊

[英]Why is there a need for a try block before catch in exception handling c++

是否可以在不使用 try 塊的情況下拋出異常並捕獲它? 前任:

int main()
{
    throw 1;
    catch(int){
       std::cerr << "caught exception\n";
    }
    return 0;
}

根據我的經驗,你必須結合使用 try 和 catch 塊。 如果在 try 塊中發生任何錯誤,則僅將其傳遞給 catch 塊。 因此,如果沒有 try 塊,那么它將不知道在哪里查找錯誤。 因此它們需要結合使用。 我不確定在 C++ 中,但在 Java 中,如果將類擴展為 throwable,則可以單獨使用 catch 塊。

在飛行異常期間,程序控制流的行為略有不同。 try-catch塊有望將程序帶回通常的控制流程。

在程序中的任何一點拋出異常時。 正常的程序控制流停止。 程序控制流現在通過運行時的異常處理機制。 這與正常情況不同。 對於正常情況,自動存儲的析構函數總是在控制流到達范圍(生命周期) }結束時運行。 對於飛行中的異常,它們比正常運行更早

考慮一下(注意評論);

MyClass foo(){
{
    MyClass c;
    c.call(balhhh); //assuming this throws

    // (1)

    ....
    return c;
 }

void bar(){
     std::map<K,V> mp;
     auto c = foo();

     // (2)

     mp.insert(c);
     ....
}

當你打電話bar ,我們可以看到控制流程是如何的每葉成熟foo()// (1)沒有其他的代碼之后// (1)的范圍內執行foo()同樣的事情發生時, foo()已經解開,我們現在在// (2)

這發生在整個堆棧展開過程中,並且遞歸地展開所有函數......直到我們回到調用std::terminate main()


現在,使用try-catch塊,編譯器生成代碼,在程序移動到 catch 塊(尋找匹配的處理程序)后掛起早期退出行為,如果處理異常,控制流將恢復正常。

考慮:

MyClass foo() 
    try {
        MyClass c;
        c.call(balhhh); //assuming this throws

        // (1)

        ....
        return c;
     }
     catch(...){
          ...
     }

void bar(){
     std::map<K,V> mp;
     auto c = foo();

     // (2)

     mp.insert(c);
     ....
}

現在,當異常離開時,控制流離開// (1)處的規范以在關聯的catch搜索處理程序,如果異常被處理,程序將返回正常控制流。 // (2)之后的代碼現在將執行...


從解釋中可以看出, try-catch塊是 C++ 標准規定的在拋出異常后恢復正常程序控制流的唯一方法。

int main()
{
    throw 1;   //fine, program control leaves the whole of main at this point.
    catch(int){    //illegal, like using an else block without an if
       std::cerr << "caught exception\n";
    }
    return 0;
}

即使上面的代碼是合法的, throw意味着控制將離開throw站點的整個封閉范圍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM