Ausnahmen: Änderungen für Ausnahmemakros in Version 3.0
Dies ist ein fortgeschrittenes Thema.
In MFC, Version 3.0 sind die Ausnahmebehandlungsmakros geändert, dass C++-Ausnahmen zu verwenden. Dieser Artikel übermittelt, wie die Änderungen das Verhalten des vorhandenen Codes beeinflussen können, der die Makros verwendet.
Dieser Artikel enthält die folgenden Themen:
Ausnahmetypen und das ERFASSUNGSmakro
Erneute auslösen von Ausnahmen
Ausnahmetypen und das ERFASSUNG Makro
In früheren Versionen von MFC, verwendet das CATCH-Makro MFC-Ablauftypinformationen, um einen Ausnahmetyp zu bestimmen; der Ausnahmetyp wird, d, mit der Übergabe bestimmt. Mit C++-Ausnahmen jedoch wird der Typ der Ausnahme immer an der Wurfssite durch den Typ des Ausnahmeobjekts bestimmt, das ausgelöst wird. Dies verursacht Inkompatibilitäten in dem seltenen Fall, in dem der Typ des Zeigers auf ausgelösten Objekt vom Typ der ausgelösten Objekts unterscheidet.
Im folgenden Beispiel wird die Auswirkung dieses Unterschieds zwischen MFC 3.0 und früheren Versionen:
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
Dieser Code verhält sich anders in Version 3.0, da Steuerelement immer dem ersten catch -Block mit einer entsprechenden AusnahmeDeklaration übergibt. Das Ergebnis des Wurfsausdrucks
THROW( (CException*) new CCustomException() );
wird als CException* ausgelöst, obwohl mit CCustomException erstellt wird. Das CATCH-Makro in MFC-Versionen 2.5 und in der vorherigen Verwendung CObject::IsKindOf, den Typ zur Laufzeit testen. Da der Ausdruck
e->IsKindOf(RUNTIME_CLASS(CException));
gilt, die ersten catch-Blocks-Erfassungen die Ausnahme. In Version 3.0, die verwendet C++-Ausnahmen, um viele der Ausnahmebehandlungsmakros zu implementieren, wird der zweite catch-Block ausgelöste CException ab.
Code so ist selten. Sie wird normalerweise, wenn ein Ausnahmeobjekt zu einer anderen Funktion, die generische CException* akzeptiert, führt "bestimmte VorTHROW" und Auslösens schließlich die Ausnahme übergeben wird.
Um dieses Problem umgehen, den Wurfsausdruck der Funktion auf den Aufrufcode verschieben und eine Ausnahme auslösen des tatsächlichen Typs bezeichnet den Compiler, als die Ausnahme generiert wird.
Erneute auslösen von Ausnahmen
Ein catch-Block kann denselben Ausnahmezeiger nicht auslösen, den er abfing.
Beispielsweise wurde dieser Code in früheren Versionen gültig, wird jedoch unerwartete Ergebnisse mit Version 3.0 haben:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH( CException, e )
{
THROW( e ); // Wrong. Use THROW_LAST() instead
}
END_CATCH
}
Mit THROW im catch-Block wird der Zeiger e gelöscht werden, um die äußere Übergabe eines ungültigen Zeigers empfängt. Verwenden Sie THROW_LAST, e erneut ausgelöst.
Weitere Informationen finden Sie unter Ausnahmen: Ausnahmen abfangen und Löschen.