例外処理 : MFC マクロと C++ 例外機構の使用
更新 : 2007 年 11 月
ここでは、MFC 例外処理マクロと C++ 例外処理キーワードの両方を同時に使ったコードを書く方法について説明します。
ここでは、次のトピックについて説明します。
例外処理用のキーワードとマクロの同時使用
CATCH ブロック内の try ブロック
例外処理用のキーワードとマクロの同時使用
MFC マクロと C++ 例外処理キーワードは、同じプログラム内に混在できますが、同じブロック内で使うことはできません。マクロの場合は、スコープから出ると、例外オブジェクトを自動的に削除しますが、例外処理用キーワードは自動的に削除しないからです。詳細については、「例外処理 : 例外のキャッチと削除」を参照してください。
例外処理マクロと C++ キーワードの最大の違いは、マクロの場合は、キャッチした例外がスコープの外に出ると、その例外を "自動的に" 削除する点です。C++ キーワードは自動的に削除しません。つまり、catch ブロックでキャッチした例外を明示的に削除する必要があります。マクロと C++ の例外処理用キーワードを同時に使った場合は、例外オブジェクトが削除されないとメモリ リークが発生し、例外オブジェクトが 2 回削除されるとヒープが破損します。
次のコードは、例外ポインタを無効にします。
TRY
{
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e) // The "inner" catch block
{
throw; // Invalid attempt to throw exception
// to the outer catch block below.
}
END_CATCH
}
CATCH(CException, e) // The "outer" catch block
{
// Pointer e is invalid because
// it was deleted in the inner catch block.
}
END_CATCH
ポインタ e は、"内側" の CATCH ブロックから出たときに削除されます。THROW ステートメントの代わりに THROW_LAST マクロを使うと、例外オブジェクトが削除されないので、外側の catch ブロックが有効なポインタを受け取れます。
TRY
{
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e) // The "inner" catch block
{
THROW_LAST(); // Throw exception to the outer catch block below.
}
END_CATCH
}
CATCH(CException, e) // The "outer" catch block
{
// Pointer e is valid because
// THROW_LAST() was used.
}
END_CATCH
CATCH ブロック内の try ブロック
CATCH ブロックの内側にある try ブロックでは、現在処理中の例外オブジェクトを再スローできません。次のコードは無効です。
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e)
{
try
{
throw; // Wrong. Causes e (the exception
// being thrown) to be deleted.
}
catch(CException* exception)
{
exception->ReportError();
}
}
END_CATCH
詳細については、「例外処理 : 例外の内容の調査」を参照してください。