3

例外クラスは、に加えてパブリック フィールドで詳細を提供する必要がありますwhat()か?

たとえばboost::property_tree::ptree_bad_path、メッセージを与える可能性のあるものを考えてみましょう:

"No such node (mynode.value1)"

パス ( "mynode.value1") にアクセスする唯一の方法は、文字列を解析することです。そのような情報を運ぶために追加のパブリックフィールドを追加することに反対する議論はありますか?

class ptree_bad_path : public ptree_error {
public:
  const std::string path; // <- additional detail by public field
....

このアプローチには欠点がありますか?

4

4 に答える 4

2

terminate理論的には、同時に2つの未処理の例外が発生した場合、プログラムが発生するリスクがあります。ただし、これはかなりまれな状況です。

  • 例外の準備中にスローする:問題ありません(ただし、期待した例外は発生しません)
  • 例外のコピー中にスローする(多くの場合、省略され、回避可能):クラッシュ
  • 巻き戻し中に投げる:クラッシュ
  • 例外の処理中にスローする(catch):罰金(結局のところ、別の例外を再スローするのが一般的です)

したがって、ここで回避できるリスクは、例外のコピーコンストラクターがたまたまスローされる可能性がある場合です。shared_ptr状態を例外内に含まれる状態に移行することで問題を回避するのは簡単です。コピーは少し「特別」になりますが(元の状態と状態を共有しているため)、適切に文書化されていれば、悲しみを引き起こすことはありません。

より大きなリスクは、スタックの巻き戻し中です。ただし、デストラクタがスローした場合にのみ発生します。

個人的に、私が使用する例外には次のものが含まれます。

  • エラーコード(APIが適切に表示/エンコードするために、すべてのエラーメッセージはコードにマップされます。これは中国語/韓国語/日本語で役立ちます)
  • いくつかの詳細を含むログメッセージ(問題の原因となったアイテムのID /名前、別の例外を変換するときの元のエラー、役立つものは何でも!)
  • 例外がスローされた関数/ファイル/行
  • 例外がスローされた時刻
  • 追加のメモ(スタックの巻き戻し中に「オンザフライ」で追加)
  • 完全なバックトレース(Linux固有の機能を使用)

ここでの唯一の論争の的となる点は、事実上クラッシュする可能性があるため、オンザフライビットです。一方、私はサーバーで作業しているので、クラッシュは簡単に(そして緊急に)修正され、過去5年間は、クラッシュを引き起こさないように十分注意していました(このように;))。

このスキームは、例外をまばらに使用する場合にのみ使用できることは明らかです。タスクごとに定期的に12の例外をスローする場合、パフォーマンスは許容できない可能性があります。一方、主要なコンパイラで使用されているゼロコストモデルは、例外的なパスにすでに厳しいペナルティを課しているため、...

于 2012-11-12T14:41:15.727 に答える
2

例外クラスには、エラーの処理に必要なすべての情報が含まれている必要があります。これは通常、問題の原因と必要なコンテキストをタグ付けすることを意味します。例外クラスにパスを格納することをお勧めします。

このアプローチには欠点がありますか?

メンバーが std::terminate を呼び出すため、メンバー自身がスローしないようにしてください。

于 2012-11-12T10:44:20.297 に答える
1

これは私の意見ですが、例外をスローする場合は、(a)例外の原因、および(b)例外がスローされた場所を知るのに十分な情報があることを確認する必要があります。

おそらく(うまくいけば)エンドユーザーに例外を表示しないので、例外をログに記録することは、純粋にサポート性を有効化/改善するものになります。したがって、開発の観点からは、基本的に、何が起こったのかを可能な限り把握できる立場になりたいと考えています。

もちろん、あなたはここで細いワイヤーを歩いているという点で正しいです。例外処理に、独自の例外をスローするリスクを伴うような複雑なコードを含めたくありません。

于 2012-11-12T10:47:12.383 に答える
0

あなたの例外は、彼らのキャッチャーが使用する準備ができている(そして喜んで)のと同じくらい多くの情報を運ぶかもしれません。特定のアプリケーションがこの追加情報を使用できる場合は、安心して独自の例外クラスを作成できます。いずれの場合も、カスタム例外を予期しない句が正しく機能std::exceptionするように、すべての例外クラスはから継承する必要があります。catch

別の問題は、サードパーティのクライアントが使用できるようにライブラリ上のこれらのクラスを公開することです。この場合、この追加情報の利点が、追加のインターフェースによってもたらされる煩わしさや、まったく使用されない可能性さえも上回るかどうかを慎重に検討する必要があります。

編集:Pubbyが言うように、への歓迎されない呼び出しを避けるために、例外クラスは決してスローしないでくださいstd::terminate()。一般に、例外関連のコードはスローされるべきではありません。これには、任意のクラスのデストラクタが含まれます。

于 2012-11-12T10:46:05.253 に答える