Partager via


Exceptions : utilisation de macros MFC et d'exceptions C++

Cet article traite des considérations relatives à l’écriture de code qui utilise les macros de gestion des exceptions MFC et les mot clé de gestion des exceptions C++.

Cet article aborde les thèmes suivants :

Mélange de mots clés et de macros d’exception

Vous pouvez combiner des macros d’exception MFC et des mot clé d’exception C++ dans le même programme. Toutefois, vous ne pouvez pas combiner des macros MFC avec des mot clé d’exception C++ dans le même bloc, car les macros suppriment automatiquement les objets d’exception lorsqu’ils sortent de l’étendue, tandis que le code utilisant les mot clé de gestion des exceptions ne le fait pas. Pour plus d’informations, consultez l’article Exceptions : Intercepter et supprimer des exceptions.

La principale différence entre les macros et les mot clé s est que les macros « automatiquement » suppriment une exception interceptée lorsque l’exception sort de l’étendue. Le code utilisant les mot clé ne le fait pas ; les exceptions interceptées dans un bloc catch doivent être supprimées explicitement. Le mélange de macros et d’exceptions C++ mot clé peut entraîner des fuites de mémoire lorsqu’un objet d’exception n’est pas supprimé, ou une altération du tas lorsqu’une exception est supprimée deux fois.

Le code suivant, par exemple, invalide le pointeur d’exception :

TRY
{
   TRY
   {
   // Do something to throw an exception.
   AfxThrowUserException();
}
CATCH(CException, e)  // The "inner" catch block
{
   throw;  // Invalid attempt to throw exception
         // to the outer catch block below.
}
END_CATCH
}
CATCH(CException, e)  // The "outer" catch block
{
   // Pointer e is invalid because
   // it was deleted in the inner catch block.
}
END_CATCH

Le problème se produit parce qu’il e est supprimé lorsque l’exécution passe du bloc CATCH « interne ». L’utilisation de la macro THROW_LAST au lieu de l’instruction THROW entraîne la réception d’un pointeur valide par le bloc CATCH « externe » :

TRY
{
   TRY
   {
   // Do something to throw an exception.
   AfxThrowUserException();
}
CATCH(CException, e)  // The "inner" catch block
{
   THROW_LAST(); // Throw exception to the outer catch block below.
}
END_CATCH
}
CATCH(CException, e)  // The "outer" catch block
{
   // Pointer e is valid because
   // THROW_LAST() was used.
}
END_CATCH

Essayer des blocs à l’intérieur des blocs Catch

Vous ne pouvez pas lever à nouveau l’exception actuelle à partir d’un try bloc qui se trouve à l’intérieur d’un bloc CATCH . L’exemple suivant n’est pas valide :

TRY
{
   // Do something to throw an exception.
   AfxThrowUserException();
}
CATCH(CException, e)
{
   try
   {
      throw;  // Wrong.  Causes e (the exception 
            // being thrown) to be deleted.
   }
   catch (CException* exception)
   {
      exception->ReportError();
   }
}
END_CATCH

Pour plus d’informations, consultez Exceptions : Examen du contenu des exceptions.

Voir aussi

Gestion des exceptions