例外処理 : MFC マクロと C++ 例外機構の使用

ここでは、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)