Partager via


Exceptions : Libérer les objets des exceptions

Cet article explique le besoin et la méthode de libération des objets lorsqu'une exception se produit.Les rubriques traitées ici sont les suivantes :

  • Gestion de l'exception localement

  • Levant des exceptions après destruction des objets

Les exceptions levées par l'infrastructure ou par votre application interrompent le flux normal du programme.Par conséquent, il est très important de effectuer un suivi proche des objets afin que vous puissiez correctement les avoir au cas où une exception est levée.

Il existe deux méthodes principales pour ce faire.

  • Gèrent les exceptions localement à l'aide de les mots clés de try et de catch , destroy tous les objets avec une instruction.

  • Supprimez tout objet dans le bloc de catch avant de lever l'exception en dehors de le bloc pour plus de gestion.

Ces deux options sont illustrées ci-dessous comme solutions à l'exemple problématique suivant :

void SomeFunc()        // Problematic code
{
   CPerson* myPerson = new CPerson;

   // Do something that might throw an exception.
   myPerson->SomeFunc();

   // Now destroy the object before exiting.
   // If SomeFunc above throws an exception this code will
   // not be reached and myPerson will not be deleted.
   delete myPerson;
}

Comme écrit ci-dessus, myPerson ne sera pas supprimé si une exception est levée par SomeFunc.L'exécution passe directement au gestionnaire d'exceptions externe suivant, contournant la sortie de fonction normale et le code qui supprime l'objet.Le pointeur vers l'objet est hors de portée lorsque l'exception partie de la fonction, et la mémoire occupée par l'objet ne sera jamais récupérée tant que le programme s'exécute.Il s'agit d'une fuite de mémoire ; elle est détectée à l'aide de diagnostic de la mémoire.

Gestion de l'exception localement

Le paradigme de try/catch fournit une méthode de programmation défensive pour éviter des fuites de mémoire et vérifier que vos objets sont détruits en cas de exception.Par exemple, l'exemple illustré précédemment dans cet article peut être réécrit comme suit :

void SomeFunc()
{
   CPerson* myPerson = new CPerson;

   try
   {
      // Do something that might throw an exception.
      myPerson->SomeFunc();
   }
   catch( CException* e )
   {
      // Handle the exception locally
      e->Delete();
   }

   // Now destroy the object before exiting.
   delete myPerson;
}

Ce nouvel exemple installe un gestionnaire d'exceptions pour intercepter l'exception et à la gérer localement.Il existe la fonction normalement et détruit l'objet.L'aspect important de cet exemple est qu'un contexte pour intercepter l'exception est généré avec les blocs try/catch.Sans frame local d'exception, la fonction ne sait jamais qu'une exception a été levée et ne doit pas l'opportunité de quitter normalement et de destruction de l'objet.

Levant des exceptions après destruction des objets

Une autre manière de gérer les exceptions est de les transmettre au contexte externe suivant de gestion des exceptions.Dans votre bloc de catch , vous pouvez effectuer certaines opérations de nettoyage de vos objets alloués localement puis lever l'exception sur pour un traitement supplémentaire.

La fonction se levante peut ou ne doive pas récupérer des objets soucier.Si la fonction libère toujours l'objet soucier avant le retour en situation normale, la fonction doit également libérer l'objet soucier avant de lever l'exception.En revanche, si la fonction ne libère pas normalement l'objet avant le retour en situation normale, puis vous devez décider au cas par cas si l'objet soucier doit être libérées.

L'exemple suivant montre comment utiliser les objets alloués localement peuvent être nettoyés :

void SomeFunc()
{
   CPerson* myPerson = new CPerson;

   try
   {
      // Do something that might throw an exception.
      myPerson->SomeFunc();
   }
   catch( CException* e )
   {
      e->ReportError();
       // Destroy the object before passing exception on.
      delete myPerson;
      // Throw the exception to the next handler.
      throw;
   }

   // On normal exits, destroy the object.
   delete myPerson;
}

Le mécanisme d'exception libère automatiquement des objets frames ; le destructeur de l'objet frame est également appelé.

Si vous appelez les fonctions qui peuvent lever des exceptions, vous pouvez utiliser des blocs de try/catch pour vous assurer que vous interceptez les exceptions et avez la possibilité de détruire tous les objets que vous avez créés.En particulier, sachez que de nombreuses fonctions MFC peuvent lever des exceptions.

Pour plus d'informations, consultez l' exceptions : Interception et supprimant des exceptions.

Voir aussi

Concepts

Gestion des exceptions dans MFC