2

このトピックはSOで広く議論されていますが、次の事実を考慮して、まだはっきりしていないいくつかのことを明らかにしたいと思います。

  1. 10年前、ハーブサッターはこの機能の使用を控えるように言っていました。

  2. 関数/メソッドがスローする可能性のある例外を指定しても、関数の本体を変更して新しいタイプの例外をスローすることを決定したときに、コンパイラが強制的に怒鳴ることはなく、関数の宣言で例外仕様を変更することを誤って忘れてしまいます。

  3. 他のいくつかの高レベル関数を呼び出す非常に高レベルの関数があり、それぞれが大量のコードを実行して結果を生成する場合、最初の関数であるすべてのエラーを指定する必要があるときに、地獄の悪夢からのメンテナンスを想像できますがスローされる可能性があり、このリストには、内部関数がスローする可能性のあるすべての例外などが含まれている必要があるため、高レベル関数と低レベル関数の間に緊密な結合が作成されます。これは非常に望ましくありません。一方、すべての例外はstd :: runtime_errorから派生します。これは、適切な方法であることがわかっています。そして、高レベルの関数がstd :: runtime_errorをスローし、それで実行されるように指定できます。しかし、ちょっと待ってください...実際に例外をどこでキャッチしますか?高レベル関数がstd::runtime_errorのみをスローすることになっている場合、MyVerySpecific例外をキャッチするtry / catchブロックでこれらの高レベル関数の1つへの呼び出しを囲むことは、かなり奇妙/厄介/悪いことではないでしょうか? ?下位レベルの関数で特定の例外をキャッチするのは良いことでしょうか。例外は、それらについては何もできませんが、より多くの情報が追加された、より一般的なコンテナーに渡されます。私は確かに、例外をフォーマットするためだけに、私が書くすべての関数にtry/catchブロックを書きたくありません。それは、すべての関数にそのパラメーターを検証することを要求するようなものであり、それは人々を狂気に駆り立てることができます、

質問:

  1. 例外仕様に関するハーブサッターの怒りは今日でも続いていますか?それ以来、何か変わったことはありますか?私は主にC++0x以前の標準に興味があります。はいの場合、このトピックは終了したと見なすことができると思います。

  2. コンパイラはこれらの例外仕様をほとんど無視しているようで、例外をキャッチする場合、99%の場合、を使用catch (const CustomException &ex)します。関数がCustomExceptionをスローするように指定するにはどうすればよいでしょうか。throw(CustomExecption)またはthrow (CustomException &)またはthrow (const CustomException &)?私はすべてのバリエーションを見てきました、そして私は最初のものに行きますが、他のものは何か意味がありますか/何か利点を追加しますか?

  3. この機能を実際にどのように使用し、同時に、上記の3番目の事実に示されている誤謬を回避するのでしょうか。

  4. 編集:ライブラリを構築していると仮定します。例外仕様を使用しない場合、ユーザーはどのような例外が予想されるかをどのように知ることができますか?彼らは確かに、APIメソッドによって内部的に呼び出される関数を確認しません...

4

2 に答える 2

2

1 /例外仕様に関するハーブサッターの怒りは今日でも続いていますか?それ以来、何か変わったことはありますか?私は主にC++0x以前の標準に興味があります。はいの場合、このトピックは終了したと見なすことができると思います。

はい、彼らはまだ保持しています。

例外仕様は次のとおりです。

  • 途中で実装されました(たとえば、関数ポインタは例外を指定しません)
  • コンパイル時にはチェックされませんが、実行時に終了します!!

一般的に、実装の詳細が漏洩するため、例外仕様には反対です。Java例外の状態を見てください...

特にC++では?例外の仕様は、ドキュメントの最も小さなエラーが電話につながる可能性があるため、自分の足を撃つようなものstd::terminateです。ほとんどすべての関数が、たとえば、std::bad_allocまたはをスローする可能性があることに注意してください。std::out_of_range

注:C ++ 11以降throw()は非推奨になり、C++17では廃止されました。代わりに、C ++ 17以降、noexcept(false)指定子を使用できます。関数ポインタでより適切にサポートされますが、コンパイル時のエラーではなく、実行時の終了につながります。


2 /コンパイラはこれらの例外仕様をほとんど無視しているようで、例外をキャッチする場合、99%の場合、catch(const CustomException&ex)を使用しますが、関数がCustomExceptionをスローするように指定するにはどうすればよいですか?throw(CustomExecption)またはthrow(CustomException&)またはthrow(const CustomException&)?私はすべてのバリエーションを見てきました、そして私は最初のものに行きますが、他のものは何か意味がありますか/何か利点を追加しますか?

コンパイラは例外仕様を無視しません。何かを見逃した場合に備えて、プログラムを確実に強制終了するために、非常に警戒するウォッチドッグ(軸)を設定します。


3 /この機能を実際にどのように使用し、同時に、上記の3番目の事実に示されている誤謬を回避しますか?

あなたの顧客はそれが非公式のままであるかどうかを感謝するでしょう、それで最も良い例は次のとおりです:

void func(); // throw CustomException

これにより、重要な例外に焦点を合わせ、「重要でない」例外をすり抜けることができます。消費者がそれらすべてを望んでいる場合は?catch(std::exception const& e)動作します。


4 /編集:ライブラリを構築していると仮定します。例外仕様を使用しない場合、ユーザーはどのような例外が予想されるかをどのように知ることができますか?彼らは確かに、APIメソッドによって内部的に呼び出される関数を確認しません...

彼らはする必要がありますか?

重要なことを文書化するかstd::exception...予期しないことに対処してください。

于 2012-06-15T14:26:34.867 に答える
0
  1. 例外仕様に関するハーブサッターの怒りは今日でも続いていますか?それ以来、何か変わったことはありますか?

私はそれを暴言とは呼びません。彼は、例外仕様に関連する問題を指摘したばかりです。

はい、それはまだ保持されます。本文で説明されているように、指定されていない例外がスローされると、プログラムは終了し、99%のアプリケーションでは受け入れられません。

  1. 関数がCustomExceptionをスローするように指定するにはどうすればよいですか?
class A
{
 //...
   void foo() throws( CustomException );
};
  1. この機能を実際にどのように使用し、同時に、上記の3番目の事実に示されている誤謬を回避するのでしょうか。

関数宣言を見ることで、ユーザーはどの例外をスローできるかがわかります。問題は、新しい例外をスローする必要がある場合、すべての関数宣言を変更する必要がある場合です。

  1. ライブラリを構築していると仮定します。例外仕様を使用しない場合、ユーザーはどのような例外が予想されるかをどのように知ることができますか?

ドキュメントを読むことによって。

于 2012-06-15T14:06:20.567 に答える