Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Opmerking
De Microsoft Foundation Classes-bibliotheek (MFC) wordt nog steeds ondersteund. We voegen echter geen functies meer toe of werken de documentatie bij.
Dit is een geavanceerd onderwerp.
In MFC versie 3.0 en hoger zijn de macro's voor het verwerken van uitzonderingen gewijzigd om C++-uitzonderingen te gebruiken. In dit artikel wordt uitgelegd hoe deze wijzigingen van invloed kunnen zijn op het gedrag van bestaande code die gebruikmaakt van de macro's.
In dit artikel worden de volgende onderwerpen behandeld:
Uitzonderingstypen en de CATCH-macro
In eerdere versies van MFC gebruikte de CATCH-macro MFC-runtimetypegegevens om het type uitzondering te bepalen; het type uitzondering wordt bepaald, met andere woorden, op de catch-site. Bij C++-uitzonderingen wordt het type uitzondering echter altijd bepaald op de plaats van de worp, door het type van het uitzonderingsobject dat wordt geworpen. Dit veroorzaakt incompatibiliteiten in het zeldzame geval dat het type van de pointer naar het geworpen object verschilt van het type van het geworpen object.
In het volgende voorbeeld ziet u het gevolg van dit verschil tussen MFC versie 3.0 en eerdere versies:
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
Deze code gedraagt zich anders in versie 3.0, omdat het besturingselement altijd wordt doorgegeven aan het eerste catch blok met een overeenkomende uitzonderingsdeclaratie. Het resultaat van de throw-expressie
THROW((CException*) new CCustomException());
wordt opgeworpen als een CException*, ook al is het geconstrueerd als een CCustomException. De CATCH-macro in MFC-versies 2.5 en eerder gebruikt CObject::IsKindOf om het type tijdens runtime te testen. Omdat de uitdrukking
e->IsKindOf(RUNTIME_CLASS(CException));
is waar, het eerste vangstblok ondervangt de uitzondering. In versie 3.0, die gebruikmaakt van C++-uitzonderingen voor het implementeren van veel van de macro's voor het verwerken van uitzonderingen, komt het tweede catch-blok overeen met het gegenereerde CExceptionblok.
Code als dit is ongebruikelijk. Dit wordt meestal weergegeven wanneer een uitzonderingsobject wordt doorgegeven aan een andere functie die een algemene CException*functie accepteert, 'pre-throw' verwerking uitvoert en ten slotte de uitzondering genereert.
Als u dit probleem wilt omzeilen, verplaatst u de throw-expressie van de functie naar de aanroepende code en genereert u een uitzondering van het werkelijke type dat bekend is bij de compiler op het moment dat de uitzondering wordt gegenereerd.
uitzonderingen voor Re-Throwing
Een catch-blok kan niet dezelfde exception pointer werpen als die het heeft opgevangen.
Deze code was bijvoorbeeld geldig in eerdere versies, maar heeft onverwachte resultaten met versie 3.0:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e)
{
THROW(e); // Wrong. Use THROW_LAST() instead
}
END_CATCH
}
Als u THROW in het catch-blok gebruikt, wordt de aanwijzer e verwijderd, zodat de buitenste catchsite een ongeldige aanwijzer ontvangt. Gebruik THROW_LAST om opnieuw te gooien e.
Zie Uitzonderingen: Uitzonderingen vangen en verwijderen voor meer informatie.