Eccezioni: conversione da macro eccezioni MFC
Questo è un argomento avanzato.
Questo articolo illustra come convertire il codice esistente scritto con macro di Microsoft Foundation Class , TRY, CATCH, THROW e così via, per usare le parole chiave di gestione delle eccezioni try
C++ , catch
e throw
. Gli argomenti includono:
Vantaggi della conversione
Probabilmente non è necessario convertire il codice esistente, anche se è necessario tenere presente le differenze tra le implementazioni di macro in MFC versione 3.0 e le implementazioni nelle versioni precedenti. Queste differenze e le successive modifiche apportate al comportamento del codice sono descritte in Eccezioni: Modifiche alle macro eccezioni nella versione 3.0.
I principali vantaggi della conversione sono:
Il codice che usa le parole chiave di gestione delle eccezioni C++ viene compilato in un file CON ESTENSIONE EXE o DLL leggermente più piccolo.
Le parole chiave di gestione delle eccezioni C++ sono più versatili: possono gestire le eccezioni di qualsiasi tipo di dati che può essere copiato (
int
,float
,char
e così via), mentre le macro gestiscono eccezioni solo di classiCException
e classi derivate.
La differenza principale tra le macro e le parole chiave è che il codice che usa le macro "automaticamente" elimina un'eccezione rilevata quando l'eccezione esce dall'ambito. Il codice che usa le parole chiave non, pertanto è necessario eliminare in modo esplicito un'eccezione intercettata. Per altre informazioni, vedere l'articolo Eccezioni: rilevamento ed eliminazione di eccezioni.
Un'altra differenza è la sintassi. La sintassi per macro e parole chiave è diversa in tre aspetti:
Argomenti macro e dichiarazioni di eccezione:
Una chiamata di macro CATCH ha la sintassi seguente:
CATCH(exception_class, exception_object_pointer_name)
Si noti la virgola tra il nome della classe e il nome del puntatore all'oggetto.
La dichiarazione di eccezione per la
catch
parola chiave usa questa sintassi:catch(exception_type exception_name)
Questa istruzione di dichiarazione di eccezione indica il tipo di eccezione gestito dal blocco catch.
Delimitazione dei blocchi catch:
Con le macro, la macro CATCH (con i relativi argomenti) inizia il primo blocco catch; la macro AND_CATCH inizia i blocchi catch successivi e la macro END_CATCH termina la sequenza di blocchi catch.
Con le parole chiave , la
catch
parola chiave (con la relativa dichiarazione di eccezione) inizia ogni blocco catch. Non esiste alcuna controparte della macro END_CATCH . Il blocco catch termina con la parentesi graffa di chiusura.Espressione throw:
Le macro usano THROW_LAST per generare nuovamente l'eccezione corrente. La
throw
parola chiave, senza argomento, ha lo stesso effetto.
Conversione
Per convertire il codice usando macro per usare le parole chiave di gestione delle eccezioni C++
Individuare tutte le occorrenze delle macro MFC TRY, CATCH, AND_CATCH, END_CATCH, THROW e THROW_LAST.
Sostituire o eliminare tutte le occorrenze delle macro seguenti:
TRY (sostituirlo con
try
)CATCH (sostituirlo con
catch
)AND_CATCH (sostituirlo con
catch
)END_CATCH (eliminarlo)
THROW (sostituirlo con
throw
)THROW_LAST (sostituirlo con
throw
)Modificare gli argomenti macro in modo che formino dichiarazioni di eccezione valide.
Ad esempio, modificare
CATCH(CException, e)
a
catch (CException* e)
Modificare il codice nei blocchi catch in modo che elimini gli oggetti eccezione in base alle esigenze. Per altre informazioni, vedere l'articolo Eccezioni: rilevamento ed eliminazione di eccezioni.
Di seguito è riportato un esempio di codice di gestione delle eccezioni tramite macro di eccezioni MFC. Si noti che poiché il codice nell'esempio seguente usa le macro, l'eccezione e
viene eliminata automaticamente:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e)
{
if (m_bPassExceptionsUp)
THROW_LAST();
if (m_bReturnFromThisFunction)
return;
// Not necessary to delete the exception e.
}
END_CATCH
Il codice nell'esempio successivo usa le parole chiave di eccezione C++, pertanto l'eccezione deve essere eliminata in modo esplicito:
try
{
// Do something to throw an exception.
AfxThrowUserException();
}
catch (CException* e)
{
if (m_bPassExceptionsUp)
throw;
if (m_bThrowDifferentException)
{
e->Delete();
throw new CMyOtherException;
}
if (m_bReturnFromThisFunction)
{
e->Delete();
return;
}
e->Delete();
}
Per altre informazioni, vedere Eccezioni: Uso di macro MFC ed eccezioni C++.