Ausnahmen: Änderungen an den Ausnahme-Makros in Version 3.0
Dies ist ein erweitertes Thema.
In MFC-Version 3.0 und höher, sind die Ausnahmebehandlung Makros geändert, um C++-Ausnahmen zu verwenden.In diesem Artikel wird mitgeteilt, wie diese Änderungen im Verhalten von vorhandenem Code auswirken können, der die Makros verwendet.
Dieser Artikel enthält die folgenden Themen:
Ausnahmetypen und das CATCH-Makro
Ausnahmen erneut auslösen
Ausnahme-Typen und das CATCH-Makro
In früheren Versionen von MFC verwendet das CATCH Makro MFC-Ablauf Typinformationen, um einen Ausnahmetyp zu bestimmen. Der Ausnahmetyp wird, d. h. in der Erfassungs Site bestimmt.Mit C++-Ausnahmen wird der Typ der Ausnahme Wurfs immer auf der Website durch den Typ des Ausnahmeobjekts angegeben wird, das ausgelöst wird.Dies verursacht Inkompatibilitäten im seltenen Fall, in dem der Typ des Zeigers auf den ausgelösten Objekt vom Typ des ausgelösten Objekts unterscheidet.
Das folgende Beispiel veranschaulicht die Folge dieses Unterschied zwischen MFC-Version 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 als in Version 3.0, da sie immer Steuerelement ersten catch den Block mit einer übereinstimmenden Ausnahme Deklaration übergibt.Das Ergebnis des Ausdrucks für Wurfs
THROW( (CException*) new CCustomException() );
wird als CException* ausgelöst, auch wenn es als CCustomException erstellt wird.Das CATCH Makro in MFC-Versionen 2.5 und früher CObject::IsKindOf verwendet, um den Typ zur Laufzeit zu testen.Da der Ausdruck
e->IsKindOf(RUNTIME_CLASS(CException));
gilt, die ersten catch-Blocks-Erfassungen die Ausnahme.In Version 3.0 der C++-Ausnahmen verwendet, um viele der Ausnahmebehandlung Makros zu implementieren, stimmt der zweite catch-Block ausgelöste CException ab.
Code so ist selten.Es erscheint normal, wenn ein Ausnahmeobjekt zu einer anderen Funktion, die ausgeführt wird, akzeptiert CException* generisches verarbeitendes "und" THROW bevor schließlich die Ausnahme ausgelöst hat.
Um dieses Problem umgehen, Wurfs den Ausdruck aus der Funktion für den Aufrufcode verschieben und dem tatsächlichen Typs eine Ausnahme auslösen wird der Compiler zum Zeitpunkt des Auslösens der Ausnahme generiert wird.
Ausnahmen erneut auslösen
Ein catch-Block kann denselben Zeiger Ausnahme auslösen, den er abfing.
Zum Beispiel wäre dieser Code in früheren Versionen gültig, wird jedoch zu unerwarteten Ergebnissen mit Version 3.0 aufweisen:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH( CException, e )
{
THROW( e ); // Wrong. Use THROW_LAST() instead
}
END_CATCH
}
Verwenden THROW im catch-Block wird der Zeiger e gelöscht werden, sodass die äußere Erfassungs Standort einen ungültigen Zeiger empfängt.Verwendung THROW_LAST, e erneut ausgelöst.
Weitere Informationen finden Sie unter Ausnahmen: Ausnahmen abfangen und Löschen.