this siteによれば、文字列または整数をスローするのに完全に使用できます。私はこれがかなりきれいで理解しやすいと思う。 throw std::runtime_error("description of what happened")
ではなく、throw "description of what happened"
の短所は何ですか?C++の例外:なぜstd :: exceptionを使用または拡張するのですか?
答えて
そのサイトは愚かであり、悪いデザインを教えています。
int
またはchar*
を投げる場合は、int
またはchar*
を使用してキャッチする必要があります。あなたはconst
でそれを修飾するかもしれません。
std::runtime_error
を投げた場合は、std::runtime_error const &
、またはその基本クラスstd::exception const &
を使用してキャッチできます。
それでは、何が良いですか?それについての良い
はあなたが最終的にstd::exception
から派生したクラスを使用して例外をスローした場合に例外をスローするために使用され、その後、あなたは関係なく
which derived classの
std::exception const&
として例外を受け入れるだけONE
catch
ブロックを、書くことができるということです。ここで
は一例です:
void f(A & a)
{
if (!check_arg(a))
{
throw std::invalid_argument("invalid argument");
}
else if (!check_size(a))
{
throw std::length_error("invalid length");
}
//code
if(someCondition)
{
//assume your_own_defined_exception's ultimate base is std::exception
throw your_own_defined_exception("condition unsatisfied");
}
//...
}
は今興味深い部分:
try
{
f(a); //it can throw exception of at least 3 types!
}
catch(std::exception const &e) //all types can be caught by just one catch!
{
//handle this case
}
良いf()
が投げる可能性という理由だけで、あなたがが catch
ブロックを書くためにを要求されないということです3つの異なるタイプの例外。 catch
を書いて、それが何らかの方法であなたに利益をもたらすならば、それらを別々に扱うことができます。しかしここに留意すべきポイントは:ではなく、の要件です!
つまり、クラス階層を利用できます。
主にあなたが他の人と仕事をしている場合、何を捕まえるかについて同意する必要があるからです。もし私がキャッチしてconst std::exception&
を投げてconst char*
を投げれば、私はあなたのものを捕まえるつもりはなく、悪いことが起こる可能性があります。
誰もがそれに固執している限り、どんなタイプがスローされ捕まえられるかは実際問題ではありません。私はstd::exception
がconst char*
より選択されていると思います。例外オブジェクトに単なる文字列以上のものを置くことができるからです。それはもっと柔軟です。
std :: exceptionから派生した例外だけをスローするようにコード内でルールを作成すると、それらをキャッチする方が簡単です。
catch (std::exception& e)
{
log_message(e);
throw;
}
をしかし、あなたは、この規則に従わない場合、あなたは、あなたがする必要がないときcatch句を記述することに終わる:他の言葉であなただけのstd ::例外で、単一のcatch節を持つことができます。あなたはintまたは文字列を投げると、あなたがすることはできません特定のエラーをキャッチしたい場合
- 彼他の回答から
あなたは本当に何かがある場合(そしてC++では、RAIIで、これは十分に稀でなければならない)、それを「飲み込む」ためには、すべてのレイヤーで捕捉して再獲得することはほとんどありません。 –
期待されていない例外のスタックトレースを生成すると便利です。これは、エラーを診断し、どこから例外が検出されたかを追跡するのに役立ちます。 – sashang
スタックは便利だと私は同意しますが、あなたのアプローチには2つの欠点があります。最初にコードが乱雑になっていますが、例外の場合に*特定の*アクションをとるべきときはもはや明らかになりません。それはgccやClangなどの一般的なコンパイラで使用されるゼロコスト例外の実装がスローに対して厳しいペナルティを課すためです。他にも、より良い選択肢があります。スローの時点でスタックをキャプチャするためのプラットフォーム固有のコードは1です。別の方法は、解読中に例外に追加される「注釈」を記録するためにRAIIを使用することです。 –
1つの追加のポイントはこれです。 すべての "int"例外をキャッチして、キャッチしたいものを比較してから、対処する準備ができていないものを再スローする必要があります。例外から継承する場合は、処理したい特定の例外をキャッチして、それらをすべて処理したい場合はstd :: exceptionを捕捉できるという利点があります。
- 1. C++の例外。 intまたはstd :: exception?
- 2. Visual Studioでユーザー(std :: exception)の例外を解除しますか?
- 3. なぜC++のstd :: exception :: whatメンバーはconstですか?
- 4. SONARはExceptionまたはRuntimeExceptionを拡張しますか?
- 5. RuntimeExceptionがExceptionを拡張するのはなぜですか?それ以外の方法はありません。
- 6. java ArrayIndexOutOfBound例外がThrowableではないIndexOutofBound例外を拡張するのはなぜですか?
- 7. Exceptionクラスを拡張する理由
- 8. C++ 11:なぜstd :: condition_variableはstd :: unique_lockを使用しますか?
- 9. C++では、std :: exceptionによってキャッチされない例外をスローすることは可能ですか?
- 10. std :: exceptionを継承したネストされたクラスで例外をスローします。
- 11. なぜObjective Cファイルに.m拡張子を使用するのですか?
- 12. カスタム例外クラス - ランタイム例外または例外を拡張する必要がありますか?
- 13. 例外がDapperの拡張
- 14. JavaScriptエラー/例外の拡張
- 15. Forループ例外の拡張
- 16. cの中でruby Exceptionクラスオブジェクトの拡張は何ですか?続き
- 17. VB.netで拡張メソッドを使用したクロススレッド例外を回避する
- 18. なぜstd :: stof、std :: stod、およびstd :: stoldは例外を伴うエラーを処理するのですか?
- 19. 人々はモジュール定義で拡張を使用するのはなぜですか?例えば
- 20. C++例外:std :: bad_alloc
- 21. Exception()の使用例
- 22. なぜstd :: mapが例外をスローしますか?
- 23. ファイルリストの拡張子は、TYPO3の例外
- 24. C++ `std`名前空間を拡張するのはいいですか?
- 25. jmimemagicが拡張ファイルsqlを持つ例外をスローするのはなぜですか?
- 26. なぜこのC++ 11 std :: regexの例でregex_error例外がスローされますか?
- 27. "java"コマンドで.class拡張子を使用しないのはなぜですか?
- 28. 一般的なC#ディクショナリを使用した拡張(つまり+)拡張メソッド
- 29. std :: shared_ptr dereferenceがnullポインタ例外(または同様のもの)をスローしないのはなぜですか?
- 30. いつ、なぜstd :: __ non_rtti_object例外が生成されますか?
したがって、基本的に継承によってエラー処理の設計が簡単になります。かなりエレガント。自分の例外クラスを定義してそのようにすれば、私は同じ結果を生み出すことができます、はい? –
@StevenLu独自の例外クラスを派生した場合は、ホイールを再作成し、std :: exceptionを捕捉することに依存するコードを破損する可能性があります。これはあなたの個人的なプロジェクトにとってはうまくいくかもしれませんが、あなたのコードを他の人に配布することは困難です。標準的なアプローチは、 'std :: exception'をサブクラス化するアプリケーション固有の例外階層を持たせることです。たとえば、すべての例外を 'Std :: exception'のサブクラスである' StevenLuException'のサブクラスにすることができます。 – sfstewman
@StevenLu:あなたの例外クラスが最終的に 'std :: exception'から派生する場合は、それは優雅なデザインです。私の例のコードでは 'your_own_defined_exception'と呼ばれる* 3番目の例外を参照してください。私は最終的に 'std :: exception'から派生しなければならないと言いました。 – Nawaz