Boost :: exceptionでtry/catchを正しく使用する方法を教えてください。
これは一例です
void Settings::init(const std::string &filename)
{
using boost::property_tree::ptree;
try
{
read_xml(filename, pt);
}
catch(boost::exception const& ex)
{
LOG_FATAL("Can't init settings. %s", /* here is the question */);
}
}
キャッチstd ::例外も必要ですか?アプリケーションを失敗させることはできないので、すべてをログに記録する必要があります。
PD:例外からログを取得するための情報を取得することも理解できませんか?
_std::exception
_には、what()
というメンバー関数があります。この関数は_const char*
_を返し、mightが何が起こったかを説明します。ログに記録したい場合(_LOG_FATAL
_がprintf
をラップしていると推測して)、次のことができます。
_catch(std::exception const& ex)
{
LOG_FATAL("Can't init settings. %s", ex.what());
}
_
_boost::exception
_の場合は、 _boost::get_error_info
_ を使用して詳細を確認できます。
おそらく答えるのが遅すぎる...しかし
<...snip...>
catch (const boost::exception& e)
{
std::string diag = diagnostic_information(e);
// display your error message here, then do whatever you need to, e.g.
LOG_FATAL("Can't init settings. %s", diag);
}
<...snip...>
他のC++と同様に、次のユニバーサルルールが適用されます。
キャッチallスローされる可能性のある例外、およびifのみそれらに有意義に応答できます。
他のすべての例外をキャッチできます(...
)同様に、ログメッセージなどを作成しますが、その後、それらを再スローする必要があります(throw;
)。一部の操作を中止する以外にコードで実行できることがない場合は、例外を処理する必要はありません。それが意味のある使用ができる場所までバブルアップさせてくださいcan。
コードでは、少なくともメモリ割り当てエラーを許容する必要があります(std::bad_alloc
)、それが理にかなっているなら、あなたはそれらをチェックすることができます。しかし、繰り返しになりますが、何を捕まえているのかわからない場合は、捕まえたものでできることはあまりありません。
あなたの「プログラムは失敗することはできない」と言うことは、それだけの意味があります。最終的に、最上位のデータ構造で割り当てエラーが発生した場合、canは何もしません。私が想像できる最良のシナリオは、メイン関数がループ内のデータを処理する場合です。その場合、ループの周りにユニバーサルtryブロックを配置でき、例外の場合は次のラウンドに進むだけです。しかし、私はそれを「例外を意味のある形で処理する」ことができる例として数えるので、それは上記の特別な場合にすぎません。一般に、メイン関数全体をtryブロックでラップすることもできますが、最終的にはそれを受け入れる必要があります。すべての場合、プログラムを中止する以外に選択肢はありません。
これは、tryブロックで実行しているコードによって異なります。 read_xmlのコードがstd :: exceptionをスローする可能性がある場合は、std :: exceptionもキャッチすることをお勧めします。よくわからない場合は、両方を捕まえるのはそれほど害にはなりません。
本当にそのタイプに関連する何かをしたい場合は、特別な例外タイプのみをcatch
する必要があります。それ以外の場合は、std::exception
を使用してください。コードが何か違うものを投げる可能性がある場合は、代わりに...
をキャッチするかstd::exception
の後にキャッチしてください。
最も明示的なものを最初に処理する必要があるよりも、複数の(特別な)例外タイプを処理する場合。