2012-02-27 6 views
25

これは愚かな質問かもしれませんが、C++では例外をスローしたいときは何を投げますか?C++の例外をスローするときに何を投げますか?

私はstd :: exceptionをスローするはずですか、それとも標準ライブラリによって予約されていますか?または、文字列またはintをスローする必要がありますか?それとも、私が適切だと思っているものを投げるべきですか?

+3

文字列やintをスローしないでください! 'std :: exception'のサブクラスを常に投げた場合、他の場所で処理されないすべての例外を処理し、例外の' what() 'を表示する' main'にcatch-all節を置くことができます。 –

答えて

31

std::exceptionから派生したクラスをスローします。 #include <stdexcept>の場合は、派生クラスの数をready-made, usefulから選択できます。

std::exceptionから派生すると、いつでも.what()を使用してテキストメッセージを得ることができるため、ハンドラーは認識可能なスタイルに従うことができます。プリミティブ型は意味情報を持たないため、投げないでください。

+10

ほとんどの場合、std :: runtime_errorから例外を派生させるべきです(実際にはstd :: exceptionから派生します) –

8

一般的に、人々はエラーメッセージを格納しないという単純な理由のために、std :: exceptionを直接スローしません。どのような方法が返ってくるかについては何もありません。 MSVCはstd :: exceptionのパラメータ化されたコンストラクタに非標準的な拡張を提供し、文字列を受け入れるため、時には混乱します。

std :: runtime_exceptionのような既存の例外クラスの中から選択することも、独自の例外クラスを定義することもできます。これはやや主観的ですが、RAIIは複数のコードブランチを持ち、異なる例外タイプのブロックをキャッチする必要がなくなるため、例外クラスの数を最小限に抑えることをお勧めします。多くの場合、RAII準拠のコードと組み合わせたメッセージは、例外から正常に回復するのに十分です。

最後に、同様の理由からstd :: exceptionから継承したすべての例外を推奨します。コードを避けることができれば、さまざまな例外タイプのさまざまなcatchブロックをコードに埋め込む必要はありません。できるだけ一般的に問題を解決してください。

+1

'std :: runtime_error'を意味しませんか? –

1

javaとは違って、あなたが望むもの(int, string, MyClass, ...)を投げることができます。 Kerrekに聞きなさい。 :)

0

通常、他の人の言ったように、std::exceptionから派生した例外の1つをスローしたいと思うでしょう。

私は時々他の型をスローしましたが、同じブロック内にキャッチされていてその値がその文脈で有用なものである場合に限ります。

+0

「同じブロック内」をキャッチしている場合は、まず例外を投げてはいけません。例外は例外的な条件ですが、そこで条件を処理できるのであれば、通常のプログラムフローの一部であるように見えます。 (例外をスローすることは地元の州を調べるよりもはるかに高価になる可能性があることを忘れないでください) –

+0

@KerrekSB、私はこれを行った正確な状況を覚えていませんが、確信しています*正常な流れの一部ではない例外的な条件であった。たぶん、代替アプローチが醜い場所に深く入れ子にされています。 –

+2

十分に公正です。例外が複雑なアルゴリズムをより明確に理解しやすくする状況がある* –

2

std::exceptionから派生した何かをスローする主な例外は、独自の例外階層を持つフレームワーク(MFCなど)を使用している場合です。その場合、一般的に階層の適切な場所から派生したいと考えています。

私は特に、例外階層を含むフレームワークの例にすぎない、クリーンな例外処理(または一般的にはクリーンデザイン)の例としてMFCを保持しようとしているわけではありません。既に例外階層を定義しているフレームワークを使用している場合は、一般に例外階層を使用する方がよいでしょう。

つまり、C++の設定とは異なり、例外は単一のルートを持つ単一の単一の階層である必要があります。標準ライブラリの場合、その単一のルートはstd::exceptionですが、他のフレームワークには選択肢があります。

関連する問題