Freigeben über


Ausnahmen: Freigeben von Objekten in Ausnahmen

Dieser Artikel beschreibt die Anforderung und die Möglichkeit der Freigabe von Objekten, wenn eine Ausnahme auftritt. Folgende Themen werden behandelt:

  • Die Ausnahme lokal behandeln

  • Ausnahmen auslösen, nachdem die Objekte zerstört wurden

Ausnahmen, die vom Framework oder von der Anwendung ausgelöst werden, unterbrechen normalen Ablaufsteuerung. Deshalb ist es sehr wichtig, nah Objekte nachverfolgen, damit sie ordnungsgemäß zu entfernen können, wenn eine Ausnahme ausgelöst wird.

Es gibt zwei primäre Möglichkeiten, um dazu.

  • Behandeln lokal unter Verwendung der try und catch Schlüsselwörter, zerstören anschließend alle Objekte mit einer Anweisung.

  • Zerstören Sie dies im catch-Block, bevor die Ausnahme den Blocks für weitere Behandlung auslösen.

Diese zwei Ansätze werden unten als Lösungen zum problematischen folgenden Beispiel veranschaulicht:

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;
}

Wie oben geschrieben, wird myPerson nicht gelöscht, wenn eine Ausnahme von SomeFunc ausgelöst wird. Die Ausführung springt direkt dem folgenden äußeren Ausnahmehandler Umgehung die Beendigung normaler Funktion und den Code, der das Objekt gelöscht werden. Der Zeiger auf das Objekt den Gültigkeitsbereich verlässt, wenn die Ausnahme die Funktion verlässt, und der Arbeitsspeicher, der vom Objekt belegt wird, wird nicht wiederhergestellt, solange das Programm ausgeführt wird. Dies ist ein Speicherverlust; daher erkannt, indem die die Speicherdiagnose verwendet.

Die Ausnahme lokal behandeln

Das try/catch Paradigma stellt ein defensives Programmiertechniken zum Vermeiden von Speicherverlusten und dafür bereit, dass die Objekte zerstört werden, wenn Ausnahmen auftreten. Beispielsweise kann das Beispiel, das oben in diesem Artikel gezeigt wurde, neu geschrieben werden, wie folgt:

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;
}

Dieses neue diesem Beispiel werden einem Ausnahmehandler, um die Ausnahme abzufangen und lokal zu behandeln. Es Beenden der Funktion und normalerweise zerstört das Objekt. Der zentrale Aspekt dieses Beispiels ist, dass ein Kontext, um die Ausnahme abzufangen mit den try/catch Blöcken eingerichtet wird. Ohne lokale Ausnahmeframe wird die Funktion nie wissen, dass eine Ausnahme ausgelöst worden war und würde nicht die Möglichkeit haben normalerweise, zu beenden und das Objekt zu zerstören.

Ausnahmen auslösen, nachdem die Objekte zerstört wurden

Eine andere Methode, Ausnahmen behandeln ist, mit dem folgenden äußeren Ausnahmebehandlungskontext weiterzuleiten. Dem catch-Block können Sie eine Bereinigung der lokal zugeordneten Objekte durchführen und die Ausnahme zur weiteren Verarbeitung anschließend auslösen.

Das auslösende Funktion muss möglicherweise Heapobjekten freigeben. Wenn die Funktion immer das Heapobjekt freigibt, bevor sie im Normalfall zurückkehrt, sollte die Funktion den Heapobjekt freigeben, bevor die Ausnahme auslöst. Wenn die Funktion nicht normalerweise dem Objekt verwendet, bevor sie im Normalfall zurückkehrt, dann müssen Sie entscheiden, von Fall zu Fall dass das Heapobjekt freigegeben werden soll.

Das folgende Beispiel zeigt, wie lokal zugeordnete Objekte bereinigt werden können:

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;
}

Der Ausnahmemechanismus gibt automatisch Frameobjekten frei; der Destruktor des Frameobjekts wird ebenfalls aufgerufen.

Wenn Sie Funktionen aufrufen, die Ausnahmen auslösen können, können Sie try/catch Blöcke verwenden, um zu überprüfen, ob Sie die Ausnahmen abfangen und eine Möglichkeit haben, alle Objekte zu zerstören, die Sie erstellt haben. Insbesondere Beachten Sie, dass viele MFC-Funktionen Ausnahmen auslösen können.

Weitere Informationen finden Sie unter Ausnahmen: Ausnahmen abfangen und Löschen.

Siehe auch

Konzepte

Ausnahmebehandlung in MFC