19

デバイスのレポートを生成するライブラリに取り組んでいます。メンバー関数は、generate_report (const std::string& no)さまざまな理由で失敗する可能性があります。

  1. 無効なレポート番号
  2. 無効な状態(これreport_generatorはFSMです)
  3. アクティブなデバイスはありません
  4. レポート生成中のエラー

これらのエラーに最適なエラー処理メカニズムはどれですか?

  • 戻るtruefalse
  • エラーコードを返す
  • アサートしてログに記録する
  • 例外をスローします
  • 上記の任意の組み合わせ

いくつかのコンテキスト情報:通常のワークフローは次のとおりです。ユーザーはデバイスをアクティブ化し、リストからレポートを選択して、「生成」をクリックします。

編集:これまでの返信ありがとうございます!私にとっては、いつアサーションを使用し、いつエラー処理を行うかが明確になりました。エラー処理に関しては、エラーコードと例外の両方に長所と短所があります。私は例外に行くと思います(そして上記のエラーのために4つのクラスを作成します)が、私はまだ本当に確信していません。私はいつも「予期しない状況」の例外を考えていました。無効なレポートは、実際には予想外ではありません。何かアドバイス?:)

4

9 に答える 9

13

これらにはそれぞれ異なる目的があります。

  • エラーコード 例外: 例外とエラー コードは、結果コードの処理方法の異なるイディオムを表します。例外はより堅牢です。結果コードは無視されるか失われる可能性があります。ライブラリは通常、どこでどのような例外がスローされ、いつエラー コードが使用されるかを明確に区別する必要があります。せいぜい、どちらか一方のみを使用してください。

  • returntrueまたはfalse: エラー コードの特殊化。通常は最悪の考えです - 良いか悪いか以外に報告することがない場合にのみ良いです (つまりmalloc、良いか悪い (= ) を返しますNULL)。

  • アサートとログ: これらはデバッグ手法であり、ユーザー/クライアントへのレポート メカニズムとして使用しないでください。Asserts は、単に「何かが起こった、それを処理できない - 終了しました」と言うだけです。

于 2009-09-07T09:18:49.887 に答える
11

アサートは正しい選択ではありません。不変条件がある場合はassertを使用します。決して起こらない何か。引数がエラー条件であり、不変ではない場合、引数がnullになることはないというassert()のようなことはしないでください。

私の場合は、インターフェイスで例外を使用し、必要に応じて、例外を使用しない場合は内部で使用される関数によってエラーコードを変換します。一貫性を保つだけです(このような場合はassertを使用しないでください)。

于 2009-09-07T09:03:58.310 に答える
5

true/false およびエラー コードと比較した例外には、いくつかの重要な利点があります。

  • 例外は無視できません。コードが例外をスローした場合、ハンドルされない例外を取得しないように、呼び出し元は例外をキャッチする必要があります。
  • 例外は、直接の呼び出し元よりも高いレベルで処理できます。エラー コードを使用すると、アプリケーションのすべての層でエラーをチェックして呼び出し元に返す必要がある状況に陥る可能性があります。

アサートは、コード内の前提条件などを表現するために使用され、開発中にバグが発見されることを願っています。ただし、リリース コードのアサートに依存するべきではありません。また、パフォーマンス上の理由から、通常、アサートはリリース コードから削除されます。

于 2009-09-07T09:39:41.577 に答える
3

例外とエラー処理については、Boost コミュニティガイド[boost.org] を読むことをお勧めします。

于 2009-09-07T09:17:19.517 に答える
2

多くの場合、どの戦略を選択するかは好みの問題です。私はあなたの図書館のクライアントと最もよく統合するものを選ぶと言います。例外戦略を採用している場合は、例外を使用します。エラーコードに慣れている場合は、それを使い続けてください。

于 2009-09-07T09:03:14.427 に答える
2

ライブラリを作成しているという理由だけで、エラー コードと例外の両方を提案するつもりです。あなたがライブラリを作っていると言っているので、あなたが制御できない人々によって書かれたコードがライブラリを利用できるようになると思います。そのため、コードをさまざまなコンパイラや、場合によっては言語にも対応できるようにすることは良いことです。

したがって、C++ 例外ライブラリをコーディングし、例外クラスの詳細を示すヘッダー ファイルを提供します。また、ユーザーのために例外を処理する C インターフェイスをコーディングします。これで、ユーザーは適切なインターフェイスにリンクできます。

#ifdef __cplusplus__
void generate_report(const std::string& rep_number, ostream& output);

extern "C" 
#endif
int generate_report(const char* rep_number, const char* outputfilename,
                    int* error_code, char* error_text, int max_error_text_len);

C 実装は C++ 実装を呼び出します。

extern "C" 
int generate_report(const char* rep_number, const char* outputfilename,
                    int* error_code, char* error_text, int max_error_text_len)
{
    ofstream os;
    try {
        os.open(outputfilename, IOS_WRITE);
        generate_report(rep_number, os);
        os.close();
        return TRUE;
    } catch (base_exception& e) {
        os.close();
        if (error_code) *error_code = e.error_code();
        if (error_text) strncpy(error_text, e.str(), max_error_text_len);
        return FALSE;
    }
}
于 2009-09-07T21:07:51.397 に答える
2

報告しているデバイスの信頼性はどの程度ですか?

接続されていない、電源が入っていない、バッテリーが切れている、何か他のことをしているなどのデバイスの大規模なクラスについては、かなり正常な状態であるため、お願いします。

この場合、デバイスが何らかの理由で使用できない場合は、ステータス コード (エラー コードではないことに注意してください) を返すことをお勧めします。

一方、これらのデバイスが非常に信頼性が高く、応答しないことが本当に例外的であると考えている場合は、例外処理が適している可能性があります。

「例外」は実際には「if (x != 0) { goto error_routine; しかし、個人的には、end_of_file のような日常的なイベントではなく、例外的な状況に対処するために例外処理を好みます。

于 2009-09-07T09:30:58.030 に答える
1
  • エラーレポートを作成/読み取るための端末にアクセスできない場合は、ログを使用する必要があります。
  • True/False を返す場合は、エラー コードと組み合わせる必要があります。例: 関数は、成功すると True を返し、エラーが発生すると False を返し、適切なエラー コード/説明で変数 (グローバルまたはパラメーター、選択) を設定します。
  • 例外: 私の意見では、それらをログ記録とエラーからの正常な回復と組み合わせるとよいでしょう。これが不可能な場合は、エラー コードを使用することもできます。例外を使用しても、それ以上のメリットはありません。
  • assert(): 他の人が指摘したように、リリース ビルドでコンパイルされるため、自由に起動します。

2c

于 2009-09-07T09:29:25.763 に答える
0

まず、一貫性を保ちます。

2番:

  • 真/偽だけでは十分ではありません。エラーコード(たとえば、false + getLastError)と組み合わせる必要があります。
  • エラーコードは高速ですが、それらを文字列に簡単に変換するためのインフラストラクチャを構築します。
  • アサート/ログ:いいえ、アプリケーションがエラーに対応できるようにする必要があります
  • 例外はエラーコードよりも低速ですが、制御フローが難しいプログラムの方が簡単です。
  • 組み合わせ:true / false +エラーコードのみが組み合わされ、残りは一貫性があります。つまり、組み合わせないでください。
于 2009-09-07T09:04:52.643 に答える