32

ほぼすべてのサンプル コードでエラー処理が省略されています (サンプル コードが対処している「問題を混乱させる」ため)。私のプログラミングの知識は主に書籍や Web サイトから得たものであり、そこで使用されているエラー処理を目にすることはめったにありません。

C++ エラー処理コードの良い例が見られる場所はどこですか? 特定の書籍、特定のオープンソース プロジェクト (参照するファイルと機能を備えていることが望ましい)、および特定の Web ページまたはサイトはすべて、ありがたく受け入れられます。

4

4 に答える 4

44

Herb Sutter と Andrei Alexandrescu の著書C++ Coding Standardsには、エラー処理と例外に関する章全体が含まれています。

  • 内部の仮定と不変条件を文書化するために自由に主張する
  • 合理的なエラー処理ポリシーを確立し、それを厳守する
  • エラーと非エラーを区別する
  • エラーセーフ コードの設計と記述
  • エラーを報告するために例外を使用することを好む
  • 値でスロー、参照でキャッチ
  • エラーを適切に報告、処理、翻訳する
  • 例外指定を避ける

すべてのトピックには例も含まれており、非常に貴重なリソースであることがわかりました.

于 2008-10-23T19:50:35.080 に答える
13

「例外を使用する」「エラーコードを使用する」は、例が示唆するほど明確ではありません。

プログラム フローのエラー コードを使用します。予期されるエラーが発生した場合は、例外をスローしないでください。たとえば、ファイルを読み取っている場合、「ファイルが見つかりません」「ファイルがロックされています」の例外をスローする場合があります。ただし、 「ファイルの終わり」に対してスローしないでください。

そうした場合、単純なループを記述することはできず、常にコードを例外ハンドラーでラップすることになります。また、例外は非常に遅いことを忘れないでください。これは、大規模なマルチスレッド サーバーでは特に重要です。(デスクトップ アプリケーションではそれほど重要ではありません)。

次に、例外階層には十分注意してください。Exceptionクラスを持っていて、そこからを派生させてNetExceptionからSMTPException、SMTP クラスを作成しても問題ないと思うかもしれません。ただし、基本クラスに汎用データを保持しない限り、その階層内のすべての種類の例外を常にキャッチする必要があります。たとえば、SMTP エラーの理由をSMTPExceptionクラスに入れる場合は、それをキャッチする必要があります。型だけをキャッチすると、メンバーExceptionにアクセスできなくなります。SMTPExceptionこの問題の適切な回避策は、基本例外クラスに文字列と int メンバーを持ち、派生型であってもそれらのみを使用することです。残念ながらstd::exception、文字列のみを提供しています:(

これを行うと、特に基本クラスの型を常にキャッチするため、単一の例外型のみを使用することを意味すると言う人もいます。

例外を使用する場合は、エラー コードの場合よりも多くのデータを入力する必要があります。エラーが発生した場合は、すぐに処理する必要があります。そうしないと、コード内で失われてしまいます。例外を除いて、ロディの例のように、投げられた場所から何層も離れた場所で捕まる可能性があります。DoCが呼び出され、 from で 2 レベルの例外を取得しますDoA。のコードに固有のエラーを指定しない限りDoA、関数からスローされたと考えることができますDoB。(単純な例ですが、呼び出しスタックの何層も下のレベルで例外が処理されるコードを見てきました。デバッグするのは不可能でした。これは特にOOプログラムに当てはまります)

うまくいけば、私はあなたに考えるのに十分なものを与えました. 問題の単純な真実は、エラー処理においてスタイルは何の意味も持たず、実用性がすべてであるということです。エラーが発生する可能性のあるすべての場所にログステートメントを配置する必要がある場合は、そうしてください。洗練された例外階層を持っているか、コードに例外ハンドラーを散らかしているよりも、コードのどこで問題が発生したか (およびどのデータが処理されたか) を確認できることの方がはるかに重要です。エラーを簡単に追跡できない場合、エラー処理コードは役に立ちません。

例外は良いです、それらを使用してください。しかし、自分が何をしているのかよく考えて、それらを誤用したり使いすぎたりしないでください。誤用された例外は、エラー処理がまったくないよりも悪いことです (クラッシュ ダンプを取得し、処理されていない例外を表示して、数秒でエラーを見つけることができるためです。食べられて無視される例外があると、詰め込まれます)。

私は長年にわたって、デバッグの最大の助けがロギングであることを発見しました。ログを書き、たくさんのログを書きます。

于 2009-04-11T14:50:39.513 に答える
6

私は、この記事で説明した例外処理を好みます。これにより、コードがクリーンになり、例外を処理するためだけにオブジェクトを明示的に作成/削除する必要がなくなります。 http://www.informit.com/articles/article.aspx?p=373339

于 2008-10-23T19:39:37.923 に答える
4

C++ を使用すると、面倒な作業の多くを例外に任せることができるため、最終的にエラー処理コードが目立たなくなります。

私の意見では、例外のある最も基本的なルール (および最も一般的に破られているルール) は次のとおりです。 例外を処理する具体的な計画がない限り、例外をキャッチしようとしないでください。

例外を使用すると、適切に設計された関数は代わりに例外をスローするだけなので、関数から返されるエラー コードについて心配する必要はありません。

C では、典型的なエラー処理シナリオは次のようになります。

int DoA() 
{
 if (location == hellInAHandcart)
  return ERROR;
 else
  RETURN OK;
}

int DoB()
{
  int err = DoA();
  if (err != OK)
     return err;
  else
     return DoSomethingElse1();
}

int DoC()
{
  int err = DoB();
  if (err != OK)
     //Handle My error here in whatever way...
}

C++ では...

void DoA() 
{
 if (location == hellInAHandcart)
  throw Exception("Gone To Hell in a Handcart");
}

void DoB()
{
  DoA();
  DoSomethingElse1();
}

void DoC()
{
  try
  {
    DoB();
  }
  catch (Exception &E)
  {
    // Handle My error here in whatever way...
  }
}
于 2008-10-23T20:11:41.400 に答える