web-dev-qa-db-ja.com

C ++エラー処理-サンプルコードの優れたソース?

あらゆる場所のサンプルコードのほぼすべての部分でエラー処理が省略されています(サンプルコードが対処している「問題を混乱させる」ため)。私のプログラミングの知識は主に本やWebサイトからのものであり、優れたものは言うまでもなく、そこで使用されているエラー処理はほとんど見られません。

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

29
Head Geek

HerbSutterとAndreiAlexandrescuの本 C++ Coding Standardsエラー処理と例外に関する章全体が付属しています

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

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

43
fhe

「例外を使用する」「エラーコードを使用する」は決して例が示すように明確です。

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

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

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

これを行うと、例外タイプが1つだけになる可能性があると言う人もいます。特に、とにかく基本クラスタイプを常にキャッチするためです。

例外を使用する場合は、エラーコードを使用する場合よりも多くのデータを例外に入力するために手間をかける必要があります。エラーがある場合は、すぐに処理する必要があります。そうしないと、コードで失われます。例外を除いて、Roddyの例のように、スローされた場所から多くのレベルでキャッチされる可能性があります。 DoCが呼び出され、DoAから2レベルの例外が発生します。 DoAのコードに固有のエラーを指定しない限り、エラーはDoB関数からスローされたと思われるかもしれません。 (簡単な例ですが、呼び出しスタックの多くのレベルで例外が処理されるコードを見てきました。デバッグするのはabstrdでした。これは特にOOプログラム)に適用されます

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

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

何年にもわたって、デバッグの最大のアシスタントはロギングであることがわかりました。ログを書き、たくさんのログを書きます。

13
gbjbaanb

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

6
Steve

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...
  }
}
4
Roddy