2016-09-16 60 views
1

對於下面的代碼,結果是「EA異常完成」,這意味着雖然我們拋出派生類,它被基類捕獲。它總是?如果是這樣,我如何使派生類捕獲,從而「EB異常已完成」出現?爲什麼要在派生類捕獲基礎?

另外我不能確切地得到throw EB()catch(EA&)是什麼意思。 catch(EA&)是否意味着catch塊獲得參考EA 對象

對不起,我的無知。如果您向我推薦一本書或其他內容來介紹異常結構,那會很有幫助。

class EA {}; 
class EB: public EA {}; 

void F() 
{ 
    throw EB(); // throw at EB(). 
} 

int main() 
{ 
    try 
    { 
    F(); 
    } 
    catch(EA&) // caught here?? 
    { 
    std::cout<<"EA Exception"; 
    } 
    catch(EB&) // why not me? every time? 
    { 
    std::cout<<"EB Exception"; 
    } 

    std::cout<<" Finished"<<std::endl; 

    return 0; 
} 
+1

一個異常總是被* first * catch塊捕獲,它可以*捕獲它,所以你的訂單是錯誤的。 –

+0

非常感謝您的回答! –

回答

1

原因:

上溯造型

派生類的

至基部。並因此總是陷入第一次捕獲。

+0

謝謝!!!!!!!!! –

1

因爲catch塊檢查您聲明它們的順序。

你第一次被EA&趕上。 EB是從EA派生的,所以這是一個有效的catch,第二個catch被忽略。

您希望首先獲得最「專業化」的例外情況。所以如果你切換catch塊它應該以另一種方式工作。

+0

非常感謝!所以拋出派生類也可以被基類捕獲,但它不是可取的,因爲它不能成爲專門的處理? –

+0

如果更改「catch」塊的順序,則可以完成此操作。也正如在另一個答案中提到的。在這些情況下,你應該得到警告。 – Hayt

+0

非常感謝你! –

1

catch語句按順序檢查。 EA&匹配,所以它被使用。 EB&永遠不能匹配。你需要首先把更具體的捕獲。

catch(EB&) // Will catch 
    { 
    std::cout<<"EB Exception"; 
    } 
    catch(EA&) // and this would catch EA objects that aren't EB. 
    { 
    std::cout<<"EA Exception"; 
    } 
+0

非常感謝!那麼EB先抓住然後EA也抓到? –

+1

不可以。只有第一個匹配的catch塊被執行。對於特定的異常,對於'const std :: exception&'和'''',有一個catch塊是很常見的。每個打印的連續不詳細的信息。 –

+0

非常感謝您的全面回答! –

3

更改catch塊的順序來修復行爲:

#include <iostream> 

class EA {}; 
class EB: public EA {}; 

void F() 
{ 
    throw EB(); // throw at EB(). 
} 

int main() 
{ 
    try 
    { 
    F(); 
    } 
    catch(EB&) // why not me? every time? 
    { 
    std::cout<<"EB Exception"; 
    } 
    catch(EA&) // caught here?? 
    { 
    std::cout<<"EA Exception"; 
    } 

    std::cout<<" Finished"<<std::endl; 

    return 0; 
} 

編譯器甚至會警告你這一點:

main.cpp:21:3: warning: exception of type 'EB' will be caught 
    catch(EB&) // why not me? every time? 
    ^~~~~ 
main.cpp:17:3: warning: by earlier handler for 'EA' 
    catch(EA&) // caught here?? 
    ^~~~~ 
+0

非常感謝!在這種情況下拋出EB()是什麼意思?你使用什麼編譯器? –

+0

@DongkyuChoi我在[coliru]使用了GCC(http://coliru.stacked-crooked.com/a/33ca04ff57d31fa6) –

+0

非常感謝您的回答! –

2

正如[except.handle]提到的標準(工作草稿):

按照外觀順序嘗試try塊的處理程序。這使得編寫不可執行的處理程序成爲可能,例如,通過在派生類的處理程序之後放置相應基類的處理程序。

這正是你所做的。確實有趣。
反轉處理程序來解決問題。

+0

非常感謝! –

相關問題