Výjimky: Změny maker pro výjimky ve verzi 3.0
Toto je rozšířená.
V MFC verze 3.0 a novější byly změněny makra zpracování výjimek pro použití výjimky C++.Tento článek vysvětluje, jak tyto změny mohou ovlivnit chování existující kód, který používá makra.
Tento článek obsahuje následující témata:
Typy výjimek a CATCH makra
Opětné vyvolání výjimky
Typy výjimek a CATCH makra
V dřívějších verzích MFC ve SKUTEČNÉ makro informace typu v době spuštění MFC slouží k určení typu výjimky; Typ výjimky je určen jinými slovy, na místě úlovek.Výjimky C++ však typ výjimky je vždy určen na webu hodit typ objektu výjimku, která je vyvolána.Ve výjimečném případě, pokud se liší od typu objektu vyvolané typ ukazatel na objekt vyvolané z tohoto důvodu nekompatibility.
Následující příklad ukazuje důsledky tohoto rozdílu mezi MFC verze 3.0 a starší verze:
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
Tento kód se chová jinak ve verzi 3.0 protože ovládací prvek předává vždy na první ve skutečné blok s odpovídající prohlášení výjimku.Výsledek výrazu throw
THROW( (CException*) new CCustomException() );
je vyvolána jako CException *, i když je konstruován jako CCustomException.Ve SKUTEČNÉ makro v MFC verze 2.5 a používá starší CObject::IsKindOf k testování typu v době běhu.Protože výraz
e->IsKindOf(RUNTIME_CLASS(CException));
je to první blok catch zachytí výjimku.Ve verzi 3.0, která používá výjimky C++ implementovat mnoha makra zpracování výjimek, odpovídá druhý blok catch vyvolané CException.
Kód tímto způsobem neobvyklé.Obvykle zobrazí, pokud objekt výjimky je předán jiné funkci, která přijímá obecný CException *, provádí zpracování "předběžné throw" a nakonec vyvolá výjimku.
Chcete-li tento problém vyřešit, přesunout hodit výraz volající kód z funkce a vyvolat výjimku aktuální typ známý kompilátoru v době, kdy je generována výjimka.
Opětné vyvolání výjimky
Blok catch nelze vyvolat stejnou výjimku ukazatel, který je zachycena.
Například tento kód byla platná v předchozích verzích, ale bude mít neočekávané výsledky s verze 3.0:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH( CException, e )
{
THROW( e ); // Wrong. Use THROW_LAST() instead
}
END_CATCH
}
Pomocí VYVOLAT v úlovku bloku způsobí, že ukazatel e k odstranění, tak, aby vnější úlovku webu obdrží neplatný ukazatel.Use THROW_LAST to re-throw e.
Další informace naleznete v tématu výjimky: zachycení a odstranění výjimky.