いくつか読んだ後、C ++では例外仕様は悪いことと見なされていることに気付きました。
int f() throw(A, B); // bad because a lot of reasons
私が理解していないのは、それを置き換える方法です。f()
の呼び出し元に、例外をキャッチする必要があることをどのように伝えることができますか?
どうですか
//throws: A if something is wrong
// B if something else is wrong
int f();
あなたはそうしない。何も言わないということは、何でも投げることができるということです。
この質問をする Java のバックグラウンドがあると思います。コンパイル時の例外チェックは、失敗した Java の実験でした。そのため、他の場所では見られません。
例外処理の一般的なルールは次のとおりです。できる限り処理します。これは通常try-catch
、ユーザーが何をしようとしても失敗したことを基本的にユーザーに伝える、非常に高いレベルに要約されます。例外から回復して操作を続行できることは非常にまれです。
もちろん、関数がスローする例外のドキュメントを提供する必要があります。これが throw 仕様の代わりになるとは考えていません (その目的は大きく異なります)。関数がスローし、 caller によって有意義に処理できる例外を文書化する必要がありますが、スローの仕様では、この関数 (およびそれが呼び出す関数) から発生する可能性のあるすべての例外をリストする必要があります。
自動ドキュメンテーション ツールに置き換えることができます。
このようなツールには、多くの場合、doxygen \exception コマンド (または \throw または \throws) のように、メソッドがスローする例外を適切にフォーマットする機能があります。コードのユーザーがドキュメントを読んでいると仮定すると、キャッチする例外を見つけることができます。
/**
* @exception A
* @exception B
*/
int f();
より有用な情報については、この質問を参照してください:関数がスローする可能性のあるすべての例外を文書化する方法は?
f() の呼び出し元に、例外をキャッチする必要があることをどのように伝えることができますか?
呼び出し元が例外をキャッチする必要があると考えているということは、設計に何か問題がある可能性があることを示しています。ファイルの終わりなど、例外ではない状況を知らせるために例外を使用していますか?
すべての可能な例外をキャッチするように即時の呼び出し元を強制することは、設計として不適切です。例:push_back
標準ライブラリ コンテナーのメンバー関数はメモリを割り当てますが、これは失敗する可能性があります。ライブラリの設計者は、呼び出し元がすべてpush_back
をtry/catch
ブロックにラップすることを期待していませんでした。意味がありません。そうすることで、コードがより醜くなり、テストが非常に難しくなります。また、メモリ不足の状態からどのように回復しますか? 大まかに言えば、これを 1 回処理するだけで、ほぼすべてのことができます。