例外処理 : 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::IsKindOf の Catch マクロ。式。
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 を使用します。
詳細については、 例外: 例外をキャッチし、削除しますを参照してください。