2016-09-16 8 views
1

以下のコードでは、結果は "EA Exception Finished"です。これは、派生クラスで投げたものの、基本クラスで捕捉したものです。それはいつもですか?もしそうなら、どのように派生クラスをキャッチすることができますか? "EB Exception Finished"は表示されますか?なぜ派生クラスでベースをキャッチするのですか?

また、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

例外は、* catch * catchブロックによって常に捕捉されるので、あなたの注文は間違っています。 –

+0

お返事ありがとうございました!!! –

答えて

1

理由:

アップキャストベースに派生クラスの

。常に最初のキャッチにはまってしまいます。

+0

ありがとう!!!!!!!!! –

1

キャッチブロックは、宣言した順序でチェックインするためです。

最初にキャッチするのはEA&です。 EBはEAから派生しているので、これは有効なキャッチであり、2番目のキャッチは無視されます。

例外的に最も特殊な例外を捕捉したいと考えています。したがって、キャッチブロックを切り替えると、別の方法で動作するはずです。

+0

ありがとう!だから、派生クラスにスローすることもベースクラスでキャッチすることができますが、それは特殊な治療することはできませんので望ましくないですか? –

+0

「キャッチ」ブロックの順序を変更すると、これを行うことができます。また別の答えで述べたように。そのような場合は警告を発するべきです。 – 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

いいえ最初に一致するキャッチブロックのみが実行されます。特定の例外、 '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](http://coliru.stacked-crooked.com/a/33ca04ff57d31fa6)でGCCを使用しました –

+0

あなたの答えに多くの感謝! –

2

[except.handle]に標準で述べたように(作業ドラフト):

tryブロックのハンドラが外観順に試行されます。これにより、たとえば、対応する基本クラスのハンドラの後に派生クラスのハンドラを配置するなど、実行できないハンドラを記述することができます。

これはまさにあなたがしたことです。確かに興味深い。
ハンドラを反転して問題を解決します。

+0

ありがとうございました! –

関連する問題