2017-01-08 1 views
6

派生クラスのオブジェクトを渡している場合は、派生クラスのcatchブロックを呼び出す必要があります。しかし、出力は、例外が基本クラスによって捕捉されたと言います。どうして?派生クラスのオブジェクトを投げているときに、基本クラスのブロックをキャッチすると例外がキャッチされるのはなぜですか?

#include<iostream> 
using namespace std; 

class Base {}; 
class Derived: public Base {}; 
int main() 
{ 
    Derived d; 
    // some other stuff 
    try { 
     // Some monitored code 
     throw d; 
    } 
    catch(Base b) { 
     cout<<"Caught Base Exception"; 
    } 
    catch(Derived d) { //This catch block is NEVER executed 
     cout<<"Caught Derived Exception"; 
    } 
    getchar(); 
    return 0; 
} 
+1

派生した大文字と小文字を区別してキャッチを移動し、次に派生した大文字を使用してキャッチを移動する必要があります。彼らは過負荷ではありません。 –

+1

二重引用符ではなく、 'catch'句が異なります。 – Oktalist

+0

[スキップジャックからの同答](http://stackoverflow.com/a/39537680/366904) –

答えて

10

扱われる必要がある派生例外の非常に特定の機能がある場合を除き、あなたがこれを使用することができ、標準的には(例として強調鉱山をワーキングドラフトの[except.handle]/4]を参照)言う:

tryブロックのハンドラは、外観順に試行されます。 [注意:これにより、のハンドラの後に最終的な派生クラスのハンドラをに置くなどして、という決して実行できないハンドラをと書くことができます。

これはまさにあなたのコードで行ったことです。
したがって、あなたの期待が何であっても、それは意図された動作だと思います。

問題を解決するために2つのハンドラを交換することができます。

+0

[deja vu](http://stackoverflow.com/a/39537680/366904) –

+0

@CodyGray面白いです。私はその答えを正直に覚えていませんでしたが、私がより多くの鉱石に続いて同じパターンを追っていくのを見るのは面白いです。これを削除する必要がありますか?問題ない。 – skypjack

+0

あなたは削除する必要はありません。私はあなたの答えを見ましたが、私はこれを複製して閉じるために質問を探しました。すでに閉鎖の世話をしたので、すべてが良いです。私はちょうどあなたが一貫していることを見て楽しいかもしれないと思った。 :-) –

1

catch句は順番にチェックされます。最初に一致すると、最も一致しません。

派生型を最初にチェックすると、それをキャッチします。

3

これについて少しは言いますが、

まず、値の代わりに参照によって例外をキャッチすることをお勧めします。これにより、例外オブジェクトが抽出された場合の例外オブジェクトのスライシングが防止されます。これは例外に固有のものではなく、継承の一般的な特徴です。

この現象の説明は、あなたが物事あなたがキャッチの順序を変更する必要があり、この方法を行う上で主張すれば、派生クラスは基本キャッチを満たすように、別の答えで指摘したように、

またhereを議論していますブロック。このプロパティを明示的に使用していますが、これを行う別の方法があります。基本クラスですべてをキャッチするだけです。別途

関連する問題