Condividi tramite


Eccezioni: rilascio di oggetti nelle eccezioni

In questo articolo viene sia richiesta e il metodo di liberare degli oggetti quando si verifica un'eccezione. Gli argomenti trattati includono

  • Gestione dell'eccezione in locale

  • Generazione di eccezioni dopo avere eliminato gli oggetti

Le eccezioni generate dal framework o dall'applicazione interrompere il normale flusso di programma. Pertanto, è molto importante tenere traccia di chiusura degli oggetti in modo da poterli correttamente automatizzati è nel caso venga generata un'eccezione.

Esistono due metodi principali per questo scopo.

  • Le eccezioni in locale utilizzando le parole chiave di Catch e di Prova, quindi elimina tutti gli oggetti con un'istruzione.

  • Eliminare qualsiasi oggetto nel blocco di Catch prima di generare un'eccezione all'esterno del blocco per operazioni di gestione.

Questi due approcci vengono illustrati in soluzioni all'esempio seguente problematico:

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

Come riportato in precedenza, myPerson non verrà eliminato se viene generata un'eccezione da SomeFunc. L'esecuzione passa direttamente al gestore eccezioni esterno seguente, ignorando exit function normale e il codice che elimina l'oggetto. Il puntatore all'oggetto dall'ambito quando l'eccezione della funzione e la memoria occupata dall'oggetto non sarà recuperata mai finché il programma. Si tratta di una perdita di memoria; viene rilevata utilizzando la diagnostica della memoria.

Gestione dell'eccezione in locale

Il paradigma di try/catch fornisce un metodo di programmazione difensivo per evitare la perdita di memoria e assicurarsi che gli oggetti vengono eliminati quando è generata un'eccezione. Ad esempio, l'esempio riportato in precedenza in questo articolo potrebbe essere riscritto come segue:

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

Questo nuovo esempio configura un gestore di eccezioni per rilevare l'eccezione e per gestirla localmente. Quindi uscire dalla funzione normalmente e elimina l'oggetto. L'aspetto importante di questo esempio è che un contesto per rilevare l'eccezione viene stabilito con blocchi try/catch. Senza un frame locale di eccezione, la funzione non saprebbe mai che un'eccezione è stata generata e non avrebbe avuto la probabilità chiudere normalmente e distruggere l'oggetto.

Generazione di eccezioni dopo avere eliminato gli oggetti

Un altro modo per gestire le eccezioni è di passarli al contesto esterno seguente per la gestione delle eccezioni. Nel blocco di Catch, è possibile eseguire una certa pulitura degli oggetti allocati in locale e quindi generare l'eccezione attiva per l'ulteriore elaborazione.

La funzione che genera può avere l'esigenza di rimuovere gli oggetti dell'heap. Se la funzione rilascia sempre l'oggetto dell'heap prima di restituire nel caso normale, la funzione deve inoltre possibile eliminare l'oggetto dell'heap prima di generare un'eccezione. Di altra parte, se la funzione normalmente non rilascia l'oggetto prima di restituire nel caso normale, è necessario decidere caso per caso se l'oggetto dell'heap deve essere rilasciato.

Nell'esempio seguente viene illustrato quanto gli oggetti allocati localmente possono essere puliti:

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

Il meccanismo di eccezione viene rilasciata automaticamente dagli oggetti frame; il distruttore dell'oggetto frame viene chiamato.

Se si chiama le funzioni che possono generare eccezioni, è possibile utilizzare i blocchi try/catch per assicurarsi di rilevare le eccezioni e avere una probabilità distruggere tutti gli oggetti creati. In particolare, tenere presente che molte funzioni MFC possono generare eccezioni.

Per ulteriori informazioni, vedere Eccezioni: Rilevazione e l'eliminazione delle eccezioni.

Vedere anche

Concetti

Gestione delle eccezioni in MFC