Excepciones: Usar macros de MFC y excepciones de C++

En este artículo se analizan las consideraciones para escribir código que usa las macros de control de excepciones de MFC y las palabras clave de control de excepciones de C++.

En este artículo se tratan los temas siguientes:

Combinación de palabras clave y macros de excepciones

Puede combinar macros de excepción de MFC y palabras clave de excepción de C++ en el mismo programa. Pero no se pueden combinar macros de MFC con palabras clave de excepción de C++ en el mismo bloque porque las macros eliminan los objetos de excepción automáticamente cuando salen del ámbito, mientras que el código que usa las palabras clave de control de excepciones no. Para obtener más información, vea el artículo Excepciones: detección y eliminación de excepciones.

La principal diferencia entre las macros y las palabras clave es que las macros eliminan "automáticamente" una excepción detectada si la excepción sale del ámbito. El código que usa las palabras clave no lo hace; las excepciones detectadas en un bloque catch se deben eliminar explícitamente. La combinación de macros y palabras clave de excepción de C++ puede provocar pérdidas de memoria si no se elimina un objeto de excepción, o daños en el montón si se elimina una excepción dos veces.

El código siguiente, por ejemplo, invalida el puntero de excepción:

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

El problema se produce porque e se elimina cuando la ejecución pasa del bloque CATCH "interno". El uso de la macro THROW_LAST en lugar de la instrucción THROW hará que el bloque CATCH "externo" reciba un puntero válido:

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

Probar bloques dentro de bloques catch

No se puede volver a iniciar la excepción actual desde dentro de un bloque try que se encuentra dentro de un bloque CATCH. El ejemplo siguiente es no válido:

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

Para más información, consulte Excepciones: Examinar contenidos de excepciones.

Consulte también

Control de excepciones