Excepciones: Liberar objetos de Excepciones

En este artículo se explica la necesidad y el método de liberar objetos cuando se produce una excepción.Entre los temas se incluyen los siguientes:

  • Administrar la excepción localmente

  • Excepciones después de eliminar objetos

Las excepciones producidas por el marco o por la aplicación interrumpe el flujo normal del programa.Por tanto, es muy importante mantener un seguimiento parecida a objetos para que se pueda eliminar correctamente de ellos en caso de que se produzca una excepción.

Hay dos métodos principales para ello.

  • Controlan las excepciones localmente mediante las palabras clave de try y de catch , entonces se destruye todos los objetos con una instrucción.

  • Destruya cualquier objeto en el bloque catch antes de iniciar la excepción fuera del bloque para aún más administrar.

Estos dos enfoques se muestra debajo como soluciones al ejemplo problemático siguiente:

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

Escrita anteriormente, myPerson no se eliminará si una excepción se produce por SomeFunc.La ejecución salta directamente al controlador de excepciones externo siguiente, omitiendo la salida de la función normal y el código que elimine el objeto.El puntero al objeto salga del ámbito cuando la excepción sale de la función, y la memoria ocupada por el objeto nunca se recuperará mientras el programa se está ejecutando.Esto es una pérdida de memoria; se detectaría mediante los diagnósticos de memoria.

Administrar la Excepción Locally

El ejemplo de try/catch proporciona un método de programación estable para evitar pérdidas de memoria y asegurarse de que los objetos se destruyeron cuando se produzcan excepciones.Por ejemplo, el ejemplo mostrado anteriormente en este caso podría reescribir como sigue:

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

Este nuevo ejemplo prepara un controlador de excepciones para detectar la excepción y para controlarla localmente.A continuación cierra la función normalmente y destruye el objeto.Lo importante de este ejemplo es que un contexto para detectar la excepción está establecido con bloques try/catch.Sin un cuadro local de excepciones, la función nunca sabría que una excepción se hubiera produce y no tendrá la oportunidad de salir normalmente y de destruir el objeto.

Excepciones después de eliminar objetos

Otra manera de controlar excepciones es pasarlas al contexto externo siguiente de control de excepciones.En el bloque catch, puede hacer cualquier limpieza de los objetos localmente asignados y después producir la excepción en para más procesamiento.

La función que produce puede o no puede necesitar desasignar objetos del montón.Si la función desasigna siempre el objeto de pila antes de volver del caso normal, la función también debe desasignar el objeto de pila antes de iniciar la excepción.Por otra parte, si la función no desasignó normalmente el objeto antes de volver del caso normal, debe decidir caso por caso si el objeto de pila se debe desasignar.

El ejemplo siguiente muestra cómo los objetos localmente asignados se pueden limpiar:

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

El mecanismo de excepción automáticamente desasigna objetos de cuadro; el destructor del objeto de marco también se denomina.

Si llama a las funciones que pueden producir excepciones, puede usar los bloques try/catch para asegurarse de que detecta las excepciones y tiene una oportunidad de destruir cualquier objeto que haya creado.En particular, tenga en cuenta que muchas funciones MFC pueden producir excepciones.

Para obtener más información, vea excepciones: Detectando y eliminar Excepciones.

Vea también

Conceptos

Control de excepciones en MFC