例外処理 : 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

詳細については、「例外処理 : 例外の内容の調査」を参照してください。

参照

概念

例外処理 (MFC)