C ++エラー処理—サンプルコードの良いソース?
-
04-07-2019 - |
質問
サンプルコードのほぼすべての部分で、エラー処理が省略されています(サンプルコードが対処している「問題を混乱させる」ため)。私のプログラミングの知識は主に書籍やWebサイトから得られたものであり、良いものはもちろんのこと、エラー処理が使用されていることはほとんどありません。
C ++エラー処理コードの良い例を見る場所はどこですか?特定の書籍、特定のオープンソースプロジェクト(参照するファイルと機能が望ましい)、および特定のWebページまたはサイトはすべて、ありがたいことに受け入れられます。
解決
Herb Sutter's and Andrei Alexandrescuの本 C ++コーディング標準には全体が付属していますエラー処理と例外に関する章
- 内部の仮定と不変条件を文書化するために寛大にアサートします
- 合理的なエラー処理ポリシーを確立し、厳密に従ってください
- エラーと非エラーを区別する
- エラーセーフコードの設計と作成
- 例外を使用してエラーを報告することをお勧めします
- 値でスロー、参照でキャッチ
- エラーを適切に報告、処理、翻訳する
- 例外の指定を避ける
すべてのトピックには例も含まれており、非常に貴重なリソースであることがわかりました。
他のヒント
"例外を使用する" と"エラーコードを使用する" は、例が示すほど明確ではありません。
プログラムフローにエラーコードを使用します。予想されるエラーがある場合は、例外をスローしないでください。例えば。ファイルを読んでいる場合、" file not found" 、" file locked" ;の例外をスローできます。ただし、" end of file" に対してはスローしないでください。
そうすると、単純なループを書くことはできません。常に例外ハンドラーでコードをラップします。また、例外は非常に遅いことを忘れないでください。これは大きなマルチスレッドサーバーでは特に重要です。 (デスクトップアプリケーションではまったく重要ではありません)。
第二に、例外階層に非常に注意してください。 Exception
クラスを作成し、そのクラスから NetException
を派生させてから、SMTPクラスの SMTPException
を派生させてもかまいません。ただし、基本クラスに汎用データを保持しない限り、その階層内のすべての種類の例外を常にキャッチする必要があります。例えば。 SMTPエラーの理由を SMTPException
クラスに入れた場合、それをキャッチする必要があります- Exception
タイプのみをキャッチした場合、にアクセスできませんSMTPException
メンバー。この問題の適切な回避策は、ベース例外クラスに文字列とintメンバーを用意し、それらを派生型に対しても使用することです。残念ながら std :: exception
は文字列のみを提供します:(
これを行うと、特にとにかく基本クラス型を常にキャッチするため、例外型が1つだけになる可能性があると言う人もいます。
例外を使用する場合は、エラーコードを使用する場合よりも多くのデータを追加するために問題を処理する必要があります。エラーが発生した場合は、すぐに処理する必要があります。そうしないと、コードで失われます。例外はありますが、Roddyの例のように、スローされた場所から多くのレベルでキャッチされる可能性があります。 DoC
が呼び出され、 DoA
から2レベルの例外を取得します。 DoA
のコードに固有のエラーを指定しない限り、 DoB
関数からスローされたと考えるかもしれません。 (簡単な例ですが、例外がコールスタックの多くのレベルで処理されるコードを見てきました。これはデバッグするのにb st rdでした。これは特にオブジェクト指向プログラムに当てはまります)
それで、うまくいけば、考えられるようになりました。問題の単純な真実は、スタイルはエラー処理では何も意味しないということです。実用性がすべてです。エラーが発生する可能性のあるすべての場所にログステートメントを配置する必要がある場合は、そうします。エレガントな例外階層を持っているか、例外ハンドラーでコードを散らかしているよりも、コードがどこで間違っていたのか(およびどのデータが処理されていたのか)を確認できることが非常に重要です。 エラーを簡単に追跡できない場合、エラー処理コードは役に立ちません。
例外は適切です。それらを使用してください。しかし、あなたが何をしているのかを考え、それらを誤用したり使いすぎたりしないでください。誤用された例外は、エラー処理をまったく行わないよりも悪いです(クラッシュダンプを取得して未処理の例外を表示し、数秒でエラーを見つけることができます。食べて無視する例外を使用すると、詰め込みます)。
長年にわたり、デバッグの最大のアシスタントはロギングであることがわかりました。ログを書き、たくさんのログを書きます。
この記事で説明した例外処理を好みます。その結果、コードがクリーンになり、例外を処理するためだけにオブジェクトの明示的な作成/削除が回避されます。 http://www.informit.com/articles/article.aspx?p=373339
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...
}
}