Exceptions : Modifications apportées aux macros d'exception de la version 3,0
Cette rubrique avancée.
Dans la version 3,0 de MFC et versions ultérieures, les macros de gestion des exceptions ont été modifiées pour utiliser des exceptions C++.Cet article indique que ces modifications peuvent affecter le comportement du code existant qui utilise les macros.
Cet article décrit les rubriques suivantes :
Types d'exception et le de CATCH
Re-lever des exceptions
Types d'exception et le de CATCH
Dans les versions antérieures de MFC, la macro de CATCH utilise les informations de type au moment de MFC pour déterminer le type d'exception ; le type d'exception est déterminé, en d'autres termes, pas pris en compte.Avec des exceptions C++, toutefois, le type d'exception est toujours déterminé au site throw par le type de l'objet exception qui est levée.Cela entraîne les incompatibilités dans les rares cas où le type du pointeur vers l'objet levé est différent du type de l'objet levé.
L'exemple suivant illustre la conséquence de cette différence entre la version 3,0 de MFC et les versions antérieures :
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
Ce code se comporte différemment dans la version 3,0 parce que le contrôle transmet toujours au premier bloc de catch avec une déclaration d'exception correspondante.Le résultat de l'expression throw
THROW( (CException*) new CCustomException() );
une est levée comme CException*, même s'il est construit comme CCustomException.La macro de CATCH dans les versions 2,5 de MFC et les utilisations plus à court terme CObject::IsKindOf de tester le type au moment de l'exécution.Étant donné que l'expression
e->IsKindOf(RUNTIME_CLASS(CException));
a la valeur true, les premiers catch de bloc catch l'exception.Dans la version 3,0, qui utilise des exceptions C++ pour implémenter plusieurs des macros de gestion des exceptions, le deuxième bloc catch correspond à CExceptionlevée.
Le code comme suit est rare.Il apparaît généralement lorsqu'un objet exception est passé à une autre fonction qui accepte un générique CException*, effectue un « pré-jet » traitement, et enfin lève l'exception.
Pour contourner ce problème, déplacer l'expression de jet de la fonction au code appelant et lever une exception de type réel connu au compilateur au moment où l'exception est générée.
Re-Lever des exceptions
Un bloc catch impossible de lever le même pointeur d'exception qu'il a intercepté.
Par exemple, ce code était non valide dans les versions antérieures, mais aura des résultats inattendus avec la version 3,0 :
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH( CException, e )
{
THROW( e ); // Wrong. Use THROW_LAST() instead
}
END_CATCH
}
À l'aide de THROW dans le bloc catch provoque le pointeur e à supprimer, afin que le site externe en compte reçoit un pointeur valide.Utilisation THROW_LAST à lever de nouveau e.
Pour plus d'informations, consultez l' exceptions : Interception et supprimant des exceptions.