Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Det här är ett avancerat ämne.
I MFC version 3.0 och senare har makron för undantagshantering ändrats för att använda C++-undantag. Den här artikeln beskriver hur dessa ändringar kan påverka beteendet för befintlig kod som använder makrona.
Den här artikeln beskriver följande avsnitt:
Undantagstyper och CATCH-makrot
I tidigare versioner av MFC använde CATCH-makrot MFC-körtidstypsinformation för att fastställa en undantagstyp; undantagets typ bestäms med andra ord på fångststället. Med C++-undantag bestäms dock undantagstypen alltid på platsen för utkast av typen av undantagsobjekt som genereras. Detta orsakar inkompatibiliteter i sällsynta fall där typen av pekare till det utslängda objektet skiljer sig från typen av det utslängda objektet.
I följande exempel visas konsekvensen av den här skillnaden mellan MFC version 3.0 och tidigare versioner:
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
Den här koden fungerar annorlunda i version 3.0 eftersom kontrollen alltid skickas till det första catch blocket med en matchande undantagsdeklaration. Resultatet av throw-uttrycket
THROW((CException*) new CCustomException());
kastas som en CException*, trots att den är konstruerad som en CCustomException.
CATCH-makrot i MFC version 2.5 och tidigare använder CObject::IsKindOf för att testa typen vid körtid. Eftersom uttrycket
e->IsKindOf(RUNTIME_CLASS(CException));
Om det är sant, fångar den första catch-satsen undantaget. I version 3.0, som använder C++-undantag för att implementera många av makrona för undantagshantering, matchar det andra catch-blocket det utslängda CException.
Kod som den här är ovanlig. Det visas vanligtvis när ett undantagsobjekt skickas till en annan funktion som accepterar en allmän CException*, utför "pre-throw"-bearbetning och slutligen genererar undantaget.
Om du vill undvika det här problemet flyttar du utkastsuttrycket från funktionen till den anropande koden och utlöser ett undantag av den faktiska typ som kompilatorn känner till när undantaget genereras.
Re-Throwing undantag
Ett catch-block kan inte utlösa samma undantagspekare som den fångade.
Den här koden var till exempel giltig i tidigare versioner, men får oväntade resultat med version 3.0:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e)
{
THROW(e); // Wrong. Use THROW_LAST() instead
}
END_CATCH
}
Om du använder THROW i fångstblocket tas pekaren e bort, så att den yttre fångstplatsen får en ogiltig pekare. Använd THROW_LAST för att åter kasta e.
Mer information finns i Undantag: Fånga och ta bort undantag.