例外処理 : MFC 3.0 での変更点

これは、高度なトピックです。

MFC バージョン 3.0 では、 C++ 例外を使用するように、例外処理マクロが変更されました。この技術情報では、これらの変更がマクロを使用する既存のコードの動作に影響する可能性があるかを示します。

ここでは、次のトピックについて説明します。

  • 例外の種類と catch のマクロ

  • 再スローする例外

例外の種類と catch のマクロ

以前のバージョンの MFC では、 Catch のマクロは、例外の型を決定するために MFC の実行時の型情報を使用した; つまり、すべての種類の例外はキャッチ側で決定されますが、です。ただし、 C++ 例外以外の例外の型は、スローされた例外オブジェクトの種類によってスローのサイトで決定されます。常にです。これにより、スローされたオブジェクトへのポインターの型がスローされたオブジェクトの型と異なるまれなケースで非互換性が発生します。

次の例は、 MFC バージョン 3.0 と旧バージョンの違いの結果を示すとおりです:

TRY
{
   THROW( (CException*) new CCustomException() );
}
CATCH( CCustomException, e )
{
   TRACE( "MFC 2.x will land here\n" );
}
AND_CATCH( CException, e )
{
   TRACE( "MFC 3.0 will land here\n" );
}
END_CATCH

このコードは、バージョン 3.0 のコントロールが最初の catch に一致する例外宣言を除いて、ブロックを常に渡すため、異なる実行します。スローの式の結果

THROW( (CException*) new CCustomException() );

CCustomExceptionとして構築された場合でも、 **CException***としてスローされます。実行時に型をテストする MFC バージョン 2.5 以前の使用中 CObject::IsKindOfCatch マクロ。式。

e->IsKindOf(RUNTIME_CLASS(CException));

TRUE の場合、最初の catch ブロックの catch は例外です。例外処理マクロの多くを実装するには、 C++ 例外を使用するバージョン 3.0 では、 2 番目の catch ブロックがスローされた CExceptionに一致します。

このようなコードはほとんどありません。通常は、例外オブジェクトがジェネリック **CException***を受け入れる別の関数に、実行処理する 「Pre」スローを最後にスローされた例外を渡すときに表示されます。

例外が生成されると、この問題を回避するには、スローの式を関数から呼び出し元のコードに移動し、コンパイラで認識される実際の型の例外をスローします。

再スローする例外

catch ブロックは、同じキャッチした例外のポインターをスローすることはできません。

たとえば、このコードは、以前のバージョンで有効ですが、 Version 3.0 の予期しない結果があります:

   TRY
   {
      // Do something to throw an exception.
      AfxThrowUserException();
   }
   CATCH( CException, e )
   {
      THROW( e );    // Wrong. Use THROW_LAST() instead
   }
   END_CATCH
}

catch ブロックの THROW を使用して外部の try-catch のサイトが無効なポインターを受け取るようにポインター e を削除します。再スロー eに THROW_LAST を使用します。

詳細については、 例外: 例外をキャッチし、削除しますを参照してください。

参照

概念

例外処理 (MFC)