次のコードスニペットを考えてみましょう:標準から例外の有効期間はネストされたハンドラによって影響を受けますか?
struct ExceptionBase : virtual std::exception{};
struct SomeSpecificError : virtual ExceptionBase{};
struct SomeOtherError : virtual ExceptionBase{};
void MightThrow();
void HandleException();
void ReportError();
int main()
{
try
{
MightThrow();
}
catch(...)
{
HandleException();
}
}
void MightThrow()
{
throw SomeSpecificError();
}
void HandleException()
{
try
{
throw;
}
catch(ExceptionBase const &)
{
// common error processing
}
try
{
throw;
}
catch(SomeSpecificError const &)
{
// specific error processing
}
catch(SomeOtherError const &)
{
// other error processing
}
ReportError();
}
void ReportError()
{
}
15.1.4項を教えてくれる:
スローされた例外の一時的なコピーのためのメモリが指定されていない方法で 割り当てられ、 3.7.3.1に記載されている場合を除く。 例外のためにハンドラが実行されている限り、 のテンポラリは持続します。特に、ハンドラが throwを実行して終了した場合、同一の 例外の別のハンドラに制御を渡すので、一時的に残ります。 例外のために実行された最後のハンドラが の場合、throw以外の手段で終了します。 一時オブジェクトが破棄され、が実装され、一時オブジェクトのメモリが に割り当て解除される可能性があります。そのような割り振り解除は、指定されていない方法で で行われます。破棄は、 ハンドラの例外宣言で宣言されたオブジェクトの破棄の直後に発生します。
main
のハンドラを「最後のハンドラ」として表示するのは正しいですか?したがって、現在の例外オブジェクトの破壊を引き起こさずに、HandleException
に任意の数の再スローとキャッチが許可されますか?
¤「main」のハンドラが最後のものです。そして、はい、あなたは、あなたが望むように何度も例外を再スローして再カウントすることができます。しかし、それは良い考えではありません。代わりに、ハンドラに(1)純粋な例外変換、または(2)純粋なロギングと終了を行わせます。このハンドラコードは、当然のことながら、失敗に対処する知識を持っていません。 Cheer&hth。、 –
@Alfありがとう。小さなコードサンプルを投稿しようと努力する中で、いくつかの重要な細部を省いたようです。実際、ExceptionBaseはboost :: exception(コンテキストデータの多くの共通部分が抽出されます)から派生しています。さらに、 'main'は実際には任意の数のCOMメソッドの1つで、適切なHRESULTコードを返す前にエラーが記録されます(一般的なコンテキストデータとエラー固有のコンテキストデータの両方で)。しかしどちらにせよ、あなたは私の質問に答えました。 –