2017-01-12 4 views
6

私は例外階層を作成しましたが、catchブロックに派生例外のメッセージを表示するようにしました。 私はこのような5つの例外だ:C++で例外を継承する

class ImagetypeException : public TGAException { 
public: 
const char* what() const throw(); 
}; 


const char* ImagetypeException::what() const throw() { 
    return "Der Bildtyp ist nicht \"RGB unkomprimiert\"."; 
} 

をそれらのすべては、STD ::例外から派生しTGAException、由来しています。

class TGAException : public std::exception { 
public: 
    virtual const char* what() const throw(); 
}; 

const char* TGAException::what() const throw() { 
    return "Beim Einlesen oder Verarbeiten der TGA-Datei ist ein unerwarteter Fehler aufgetreten!"; 
} 

だから私は明らかに私のコードの中でいくつかの点でこれらを投げると、それは良いアイデアかもしれないと思った、私は必要なキャッチブロックの量を最小限にしたいです。

catch (TGAException e) { 
     cout << e.what() << endl; 
    } 

私はこのようにそれを行う場合は、印刷されるメッセージは、TGAExceptionから1ですが、私はそれがより具体的な派生メッセージを表示します。 これを私が望むように動作させるためには、どんなに恥ずかしいことがありますか?あなたはこのようにキャッチすると

+4

'catch(TGAException&e)'のように参照によってキャッチします。値でキャッチすると、例外オブジェクトを変更しようとしていないので、[スライス](https://en.wikipedia.org/wiki/Object_slicing) –

+1

がよりよく、const参照でキャッチされます。 @IgorTandetnikあなたはこれを答えにする必要があります(または私はしかし私は担当者を盗もうとしていません) –

+1

あなたは参照することによってキャッチするまで*オブジェクトスライシング*をやっています。 –

答えて

9

catch (TGAException e) { 
    cout << e.what() << endl; 
} 

コンパイラは、元の例外のコピーを作成し、Eに割り当てます。 TGAExceptionコピーコンストラクターを使用するため、catchブロック内に見られる例外はImagetypeExceptionではなく、TGAExceptionです。この現象をオブジェクトスライシングといいます。

あなたはこのようにそれをキャッチした場合:

catch (const TGAException & e) { 
    cout << e.what() << endl; 
} 

はいかなるコピーは必要ありません、それはあなたがそれが期待どおりに動作します。

一般的なガイドライン:常に参照によって例外をキャッチし、ほとんど常にconst参照でキャッチします。

+0

!非常に有用で素早い答え:) 最初のところにnoob質問-_- ' – Awesome36

+1

いいえ。良い質問です。経験豊富なC++プログラマがオブジェクトのスライスを超えた回数に驚くかもしれません(注意:パラメータや戻り値が値渡されたり、ターゲットがポインタや参照でないときに代入されても、メソッド呼び出しで発生する可能性があります)。 –