Condividi tramite


Eccezioni: utilizzo di macro MFC ed eccezioni C++

Questo articolo illustra le considerazioni per la scrittura di codice che usa sia le macro di gestione delle eccezioni MFC che le parole chiave di gestione delle eccezioni C++.

Questo articolo include gli argomenti seguenti:

Combinazione di parole chiave di eccezione e macro

È possibile combinare macro di eccezioni MFC e parole chiave di eccezione C++ nello stesso programma. Tuttavia, non è possibile combinare macro MFC con parole chiave di eccezione C++ nello stesso blocco perché le macro eliminano automaticamente gli oggetti eccezione quando escono dall'ambito, mentre il codice che usa le parole chiave di gestione delle eccezioni non lo è. Per altre informazioni, vedere l'articolo Eccezioni: rilevamento ed eliminazione di eccezioni.

La differenza principale tra le macro e le parole chiave è che le macro "automaticamente" eliminano un'eccezione rilevata quando l'eccezione esce dall'ambito. Il codice che usa le parole chiave non lo è; Le eccezioni rilevate in un blocco catch devono essere eliminate in modo esplicito. La combinazione di macro e parole chiave di eccezione C++ può causare perdite di memoria quando un oggetto eccezione non viene eliminato o il danneggiamento dell'heap quando un'eccezione viene eliminata due volte.

Il codice seguente, ad esempio, invalida il puntatore all'eccezione:

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

Il problema si verifica perché e viene eliminato quando l'esecuzione viene superata dal blocco CATCH "interno". Se si usa la macro THROW_LAST anziché l'istruzione THROW, il blocco CATCH "esterno" riceverà un puntatore valido:

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

Provare blocchi all'interno di blocchi catch

Non è possibile generare nuovamente l'eccezione corrente dall'interno di un try blocco che si trova all'interno di un blocco CATCH . L'esempio seguente non è valido:

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

Per altre informazioni, vedere Eccezioni: Esame del contenuto delle eccezioni.

Vedi anche

Gestione delle eccezioni