Partilhar via


Exceções: liberando objetos em exceções

Este artigo explica a necessidade e o método de liberar objetos quando ocorre uma exceção. Os tópicos incluem:

  • Tratando a exceção localmente

  • Lançando exceções destruído depois de objetos

As exceções lançadas pela estrutura ou pelo seu aplicativo interrompem o fluxo de programa normal. Assim, é muito importante manter a próximo controle de objetos de forma que você pode descartar corretamente no caso de uma exceção é gerada.

Há dois métodos principais para fazer isso.

  • As exceções de identificador que usam localmente as palavras-chave de try e de catch , destroem todos os objetos com uma instrução.

  • Destruir qualquer objeto no bloco de catch antes de gerar a exceção fora do bloco para manipulação adicional.

Essas duas abordagens são ilustradas em como soluções ao exemplo problemático:

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

Como gravado acima, myPerson não será excluído se uma exceção é gerada por SomeFunc. A execução pular diretamente ao manipulador externo seguinte de exceção, ignorando a saída da função normal e o código que exclui o objeto. O ponteiro para o objeto sai do escopo quando a exceção sai da função, e a memória ocupada pelo objeto será recuperada nunca como o programa está em execução. Este é um vazamento de memória; o será detectado usando o diagnóstico de memória.

Tratando a exceção localmente

O paradigma de try/catch fornece um método de programação defensivo para evitar possíveis vazamentos de memória e assegurar que os objetos a serem destruídos quando as exceções ocorrem. Por exemplo, o exemplo mostrado anteriormente neste artigo pode ser reescrito como segue:

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

Esse novo exemplo configura um manipulador de exceção para capturar a exceção e para tratá-la localmente. A função é encerrado normalmente e destrói o objeto. O aspecto importante deste exemplo é que um contexto para capturar a exceção é estabelecido com os blocos de try/catch . Sem um quadro local de exceção, a função nunca saberia se uma exceção tiver sido lançada e não teria a possibilidade é encerrado normalmente e destruir o objeto.

Lançando exceções destruído depois de objetos

Outra maneira de tratar exceções é transmiti-los sobre o contexto externo seguinte manipulação de exceções gerais. No bloco de catch , você pode fazer alguma limpeza de seus objetos atribuídos localmente e depois lançar exceção em para processamento posterior.

A função de reprodução pode ou não precise desaloque objetos do heap. Se a função sempre desaloca o objeto do heap antes de retornar os casos normais, a função também deverá desalocar o objeto do heap antes de gerar a exceção. Por outro lado, se a função desaloca normalmente o objeto antes de retornar os casos normais, você deve decidir EM UMA base casuística se o objeto do heap deve ser desalocada.

O exemplo a seguir mostra como os objetos localmente atribuídos podem ser limpos:

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

O mecanismo de exceção desaloca automaticamente objetos do quadro; o destruidor do objeto do quadro também é chamado.

Se você chamar funções que podem lançar exceções, você pode usar blocos de try/catch para garantir que o capturar exceções e tem uma possibilidade destruir todos os objetos que você criar. Em particular, lembre-se de que muitas funções MFC podem lançar exceções.

Para obter mais informações, consulte Exceções: Capturando e excluindo exceções.

Consulte também

Conceitos

Tratamento de exceções em MFC