2011-08-07 9 views
11

私はいくつかのエラー報告を行う必要があるいくつかのライブラリ関数を書いています。私は戻り値ではなく例外を使いたい。C++の例外。 intまたはstd :: exception?

私は例外をスローする私の関数を書いています。

例:

if(strm->atEnd()){ 
    // unexpected end of stream 
    throw -2; 
} 

私の質問があり、このメソッドはOKですか?または、std :: exceptionから派生した例外をスローする必要がありますか?

どのようにstd :: exceptionの方が優れていますか? (キャッチを使用できる以外)(std :: exception & e)

例外をスローするのは悪い練習ですか? (すべてのint値はdoxygenコメントに記述されています)

私はなぜオブジェクトを投げるべきなのかについての理由は見当たりません。

+2

私は一緒のものをハッキングしていたときにそれを行うことがあります。しかし、私が終わったら、それは常に(std :: rtuntime_errorから派生した)実際の例外オブジェクトを生成します。これにより、すべての例外処理コードが単純化されます。 main()でそれを捕まえてください。どのコンポーネントがエラー-345678を生成したかをどのように知っていますか? –

答えて

0

は、なぜあなたはこれをしない:-2のタイプはどちらもstd::exceptionでもstd::exceptionから派生しているため

if(strm->atEnd()){ 
    // unexpected end of stream 
    throw std::exception("-2"); 
} 

throw -2が悪いです。

それとも、より良いとして独自のクラスを記述する必要があります。読みやすくなる

class FileException : std::exception 
{ 
     //... 
}; 

そして

throw FileException("Unexpected end of stream"); 

+2

それは意味がないので? – Johnsyweb

+4

個人的に私は自分自身の例外クラスの派生を止めました(私は単にstd :: runtime_errorを使います)。特別な例外を捕まえて修正できる特定の状況がない限り。私ができることはログだけですし、std :: runtime_errorは普通は完璧な選択です。注意:FileExceptionはおそらくstd :: runtime_errorから派生するはずです(std :: exceptionにはエラーメッセージを受け取るコンストラクタがありません)。sub note:MSはstd :: exceptionへの標準拡張ではありません。 。 –

+0

なぜ "-2"を残しておきますが、それを例外の理由にしますか? –

3

std::exceptionから派生した例外をスローする必要があります。 std::runtime_error

既存のコードのほとんどは、通常のC++例外がstd::exceptionであることを前提としています。その他のものは、非常に高いコントロールレベル(mainなど)まで伝播する「ハード例外」です。

たとえば、既存のコードではほとんどの場合、intの妥当なメッセージは記録されません。それは単に "不明な例外タイプ"になります。

乾杯& HTH。、

16

あなたはstd::exceptionに基づいて例外をスローする必要があります。

throw std::runtime_error("unexpected end of stream") 

だけエトセトラこれはcatchにどれだけはるかに簡単だと思い、ログ、。また、無駄なコメントを削除し、コードからマジックナンバーを削除することもできます!

このメッセージをエンドユーザに送信して、問題を解決することができます。彼らはあなたのコード内のコメントを読むことはできません(あなたのDoxygenの出力を読むことはありません)。そして、 `-2 'が何を意味するのかは分かりません。

7

私の質問は、このメソッドはOKですか?

可読性を考えてください。

throw CUnexpectedEndOfStream(); 

throw -2 

よりも読みやすいと思いませんか?

多くの場合、デバッガの平均TONSが-2より大きくスローされたCUnexpectedEndOfStreamのインスタンスが表示されませんでした。 CUnexpectedEndOfStreamには、読み込みできなかったファイルや問題の性質に関する情報など、問題に関する有用な情報が格納されていることは言うまでもありません。

std :: exceptionから派生した例外をスローする必要がありますか?

std::exceptionは、他の例外を整理する方法を選択した場合に役立ちます。クライアントコードが使用できる便利な基本クラスです。例外によってはstd::runtime_errorを使用することもできます。

例外をスローするのは悪い練習ですか? (すべてのint値はdoxygenコメントに記録されています)

誰が悪い習慣であると言いましたか?例外をスローすることは、例外的な状況を処理するための素晴らしい方法です。私がスローする例外のほとんどは、クライアントコードが想定していたこと、つまり自分のコードのユーザーが契約に違反したことによって妨げられる可能性のあるものが原因です。しかし、OSエラー、ディスクがいっぱいになるなど、他にも多くの例外的な例外が存在します。プログラムの一部ではないすべてのものが正常に流れます。もっと重要なのは、プログラムの通常のフローに含まれていないため、パフォーマンスについて心配する必要はありません。

例として、特定のメッセージ解析エラーが発生したことをトリガするために例外を使用しました。しかし、これらの解析エラーは、例外処理と問題の入力と再解析を開始した時点で頻繁に発生することがわかりました。しばらくすると、私は、より読みやすい解決策は、問題をパーズコードで直接修正し、例外的なケースのように扱うのを止めることになることに気付きました。解析の決定を下したコードはすべて1か所に戻され、酔っている船員のように例外を投げているわけではありません。

+0

ISTM彼は具体的に*** int例外を投げているかについて質問しています***。 –

9

例外は、例外の例外です。彼らはあなたが最適化について心配するべき最後のものです!

ドナルド・クヌースは言った:

を私たちは、時間の約97%を言う、小さな効率を忘れる必要があります。例外として、時期尚早の最適化はまた、すべての悪

のルートであるオブジェクトをもエラーに関する情報を持ちます。

たとえば、ファイルが読み取れないという例外があります。オブジェクト例外をスローすると、そのオブジェクトはファイル名を持つことになります。このファイル名はintでは持てません。

例外の起点が不明で(スタックが深い)、誰もそれをキャッチしない場合、例外が適切な情報を持つオブジェクトであれば、プログラムのデバッグが容易になります。

-6

理論的には、複雑な例外をいつでも投げることができますが、ほとんどの場合、必要ないかもしれません。

私の質問は、このメソッドは問題ありませんか?

はい、いいえ理論的には、それは練習ではありませんが、それは良いことではありません(下記参照)。しかしまだやっているのであれば、少なくとも私は#defineに読みやすくするためのエラーコードを提案しています。

#define UNEXPECTED_END_OF_STREAM -2 

if(strm->atEnd()){ 
    // unexpected end of stream 
    throw UNEXPECTED_END_OF_STREAM; 
} 

エラーコード/例外として-ve数値を投げることは非常に珍しいことであり、おそらく嫌になるでしょう。実際に人々はあなたが何をしたいのか(ほとんどの場合は少なくとも)、つまりエラーを捕まえることを正確に行うにもかかわらず、intの例外を投げ捨ててしまいます。

私がスローする最も一般的な例外は、単純な文字列例外をスローするために変わったstd :: runtime_error( "My error") `です。ほとんどの場合、基本的な例外はすべて私たちが必要とするもので、エラーを検出して返します。

実際に例外処理の中心であるtry-catchブロックの利点をいつでも得ることができます。 int例外をスローする場合も同様です。私はintがエラーコードを示す可能性が高いと思います。ときどきこれは、dllの内部で例外を使用しているが、代わりにエラーコードを外部に返す必要があると言う必要があります。私はあなたの質問が本当にこの問題に沸騰すると思う、私はint例外を投げることができますし、私はする必要がありますか?

でも、あなたはそれを行うことができますが、int例外を投げることは最もエレガントなことではありません。どうして? intはプリミティブなデータ時間であり、オブジェクト指向をC++で考えると思うので、オブジェクトをスローする方がよいでしょう。これは、エラーコードintをオブジェクトにカプセル化し、そのオブジェクトをスローする必要があるかもしれないことを意味するかもしれません。おそらく、あなたがそれをやっているときには、エラーを説明する文字列を追加するのも良い考えです。ここに私が過去にしたことがあります。例外クラスをstd::runtime_errorから派生させ、エラーコードを追加しました。あなたは例外/エラーコードをスローするようにしたいとき

class my_error : public std::runtime_error 
{ 
public: 
    my_error(std::string const& msg, int code); 
    virtual ~my_error(void); 

    // the error code which you want to throw 
    int errCode; 
}; 

は今、あなたが実行します。

throw my_error("this is my own error!", UNEXPECTED_END_OF_STREAM); 
+1

-1:ホッとした。あなたは積極的にこのようなアドバイスを公開してC++コミュニティに害を及ぼしています。 –

+2

どのような壮大な失敗。 – Puppy

+0

@DeadMG何が問題なのですか? – zar

関連する問題