Excepciones: Convertir desde macros de excepciones de MFC
Este es un tema avanzado.
En este artículo se explica cómo convertir el código existente escrito con macros de Microsoft Foundation Class ( TRY, CATCH, THROW, etc.) para usar las palabras clave try
, catch
y throw
de control de excepciones de C++. Contenido de los temas:
Ventajas de la conversión
Probablemente no necesite convertir el código existente, aunque debe tener en cuenta las diferencias entre las implementaciones de macros en la versión 3.0 de MFC y las implementaciones de versiones anteriores. Estas diferencias y los cambios posteriores en el comportamiento del código se describen en Excepciones: cambios en las macros de excepción en la versión 3.0.
Las ventajas principales de la conversión son las siguientes:
El código que usa las palabras clave de control de excepciones de C++ se compila en un archivo .EXE o .DLL un poco más pequeño.
Las palabras clave de control de excepciones de C++ son más versátiles: pueden controlar excepciones de cualquier tipo de datos que se pueda copiar (
int
,float
,char
, etc.), mientras que las macros controlan solo las excepciones de la claseCException
y las clases derivadas de esta.
La principal diferencia entre las macros y las palabras clave es que el código que usa las macros "automáticamente" elimina una excepción detectada cuando la excepción sale del ámbito. El código que usa las palabras clave no lo hace, por lo que debe eliminar explícitamente una excepción detectada. Para obtener más información, vea el artículo Excepciones: detección y eliminación de excepciones.
Otra diferencia es la sintaxis. La sintaxis de macros y palabras clave difiere en tres aspectos:
Argumentos de macro y declaraciones de excepciones:
Una invocación de macro CATCH tiene la sintaxis siguiente:
CATCH(exception_class, exception_object_pointer_name)
Observe la coma que hay entre el nombre de clase y el del puntero de objeto.
La declaración de excepción de la palabra clave
catch
usa esta sintaxis:catch(exception_typeexception_name)
Esta instrucción de declaración de excepción indica el tipo de excepción que controla el bloque catch.
Delimitación de bloques catch:
Con las macros, la macro CATCH (con sus argumentos) comienza el primer bloque catch; la macro AND_CATCH comienza los bloques catch siguientes y la macro END_CATCH finaliza la secuencia de bloques catch.
Con las palabras clave, la palabra clave
catch
(con su declaración de excepción) comienza cada bloque catch. No hay ningún equivalente en la macro END_CATCH; el bloque catch termina con su llave de cierre.Expresión throw:
Las macros usan THROW_LAST para volver a generar la excepción actual. La palabra clave
throw
, sin argumento, tiene el mismo efecto.
Realización de la conversión
Conversión de código mediante macros para usar las palabras clave de control de excepciones de C++
Busque todas las repeticiones de las macros MFC TRY, CATCH, AND_CATCH, END_CATCH, THROW y THROW_LAST.
Reemplace o elimine todas las repeticiones de las macros siguientes:
TRY (reemplácela por
try
)CATCH (reemplácela por
catch
)AND_CATCH (reemplácela por
catch
)END_CATCH (elimínela)
THROW (reemplácela por
throw
)THROW_LAST (reemplácela por
throw
)Modifique los argumentos de macro para que formen declaraciones de excepción válidas.
Por ejemplo, cambie
CATCH(CException, e)
to
catch (CException* e)
Modifique el código de los bloques catch para que elimine los objetos de excepción según sea necesario. Para obtener más información, vea el artículo Excepciones: detección y eliminación de excepciones.
Este es un ejemplo de código de control de excepciones mediante macros de excepción de MFC. Tenga en cuenta que, puesto que el código del ejemplo siguiente usa las macros, la excepción e
se elimina automáticamente:
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
El código del ejemplo siguiente usa las palabras clave de excepción de C++, por lo que la excepción se debe eliminar explícitamente:
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();
}
Para obtener más información, vea Excepciones: uso de macros de MFC y excepciones de C++.