簡體   English   中英

C++ 如果拋出異常且該異常與捕獲的異常類型不匹配,則 try-catch 語句的行為是什么?

[英]C++ What is the behavior of a try-catch statement if an exception is thrown, and that exception does not match the type of exception caught?

我有興趣進一步了解以下代碼邏輯的行為方式:

try
{
    // might, or might not do this: throw ExceptionTypeA;
    function_which_might_throw_exception_type_a();
    
    do_A(); // do we do A?
}
catch(ExceptionTypeB)
{
    // B will never be done
    do_not_do_B();
}

// C is always done (Edit: should always be done, but actually isn't)
do_C();

簡而言之,這個問題可以簡單表述為:function do_A會被調用嗎?*

*[如果function_which_might_throw_exception_type_a()確實throw ExceptionTypeA; ...當然很清楚,如果function_which_might_throw_exception_type_a()沒有拋出異常,就會調用do_A() 。]

上面的偽代碼應該表示拋出的異常類型與catch子句中捕獲的異常類型不同。

換句話說,雖然有catch子句,但這里不會捕獲異常,因為它不是正確的類型。

在這種情況下,編譯器是生成一個 output 來完全跳過對do_A()的調用,還是編譯器生成一個 output 其中調用了do_A() () ?

我相當有信心,如果在 try 塊中拋出任何異常,那么執行路徑是立即離開 try 塊。 也就是說,我認為上面的偽代碼中並沒有調用do_A() (假設 function function_which_might_throw_exception_type_a()確實拋出ExceptionTypeA 。)

但是我想檢查一下,因為我開始懷疑了。

僅供參考:我正在看一段代碼,更明智地寫成:

try
{
    // might, or might not do this: throw ExceptionTypeA;
    function_which_might_throw_exception_type_a();
    
    do_A(); // do we do A?

    // C **should** always be done
    do_C()
}
catch(ExceptionTypeB)
{
    // B will never be done
    do_not_do_B();
}
return something;

但是,我認為這不等同於第一個偽代碼。

由於C++沒有try-catch-finally類型的語句,所以不能這樣表達邏輯。 (但我認為如果可以的話會更好。)

會調用 function do_A 嗎?

簡而言之——不。 try塊內拋出異常時,該塊將立即退出。 如果拋出的異常類型未由相應的catch塊處理,那么它將被處理得非常像在try塊外拋出的異常(可能導致堆棧展開,但最終導致程序終止)。

如果你希望你的do_C() function 被稱為“總是”,無論拋出什么類型的異常,那么你應該在你的其他具體之后添加一個catch(...) (稱為“catch-all clause”)塊catch塊。 這可以是一個空語句/塊; 如果是這樣,拋出的異常仍會被捕獲(即不會進一步傳播),但不會采取任何特定操作。

實現您想要的東西的一種可能方法如下:

try
{
    // might, or might not do this: throw ExceptionTypeA;
    function_which_might_throw_exception_type_a();
    
    do_A(); // If the above throws, this WILL NOT be executed
}
catch(ExceptionTypeB)
{
    // B will never be done
    do_not_do_B();
}
catch(...) {} // This will catch "ExceptionTypeA" but do nothing about it ...
do_C();       // Will 'always' execute (unless an earlier catch re-throws)
return something;

暫無
暫無

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

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