Compartilhar 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:

  • Tratamento da exceção localmente

  • Gerar exceções após a destruição de objetos

Exceções geradas pela estrutura ou pelo seu fluxo de programa normal de interrupção do aplicativo.Assim, é muito importante manter controle fechar dos objetos para que você pode desfazer adequadamente no caso de uma exceção é lançada.

Há dois métodos principais para isso.

  • Manipular exceções localmente usando o tente e catch palavras-chave, em seguida, destruir todos os objetos com uma instrução.

  • Destruir qualquer objeto de catch bloco antes de lançar a exceção fora do bloco de tratamento mais.

Essas duas abordagens são ilustradas abaixo como soluções para o exemplo seguinte problemática:

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 escrito acima, myPerson não serão excluídos se uma exceção é lançada por SomeFunc.Execução saltará diretamente para o próximo manipulador de exceção externa, ignorando a saída da função normal e o código exclui o objeto.Ponteiro para o objeto sai do escopo quando a exceção deixa a função e a memória ocupada pelo objeto nunca será recuperada, desde que a execução do programa.Este é um vazamento de memória; ele seria detectado usando o diagnóstico de memória.

Tratamento da exceção localmente

O try/catch paradigma fornece um método de programação defensivo para evitar vazamentos de memória e garantir que os objetos são destruídos quando ocorrem exceções.Por exemplo, o exemplo mostrado anteriormente neste artigo poderia ser reescrito da seguinte maneira:

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 exemplo novo configura um manipulador de exceção para capturar a exceção e manipulá-lo localmente.Em seguida, sai a função normalmente e destrói o objeto.O aspecto importante deste exemplo é um contexto para capturar a exceção é estabelecido com a try/catch blocos.Sem um quadro de exceção local, a função jamais saberia que uma exceção tivesse sido lançada e não terá a chance de sair normalmente e destruir o objeto.

Gerar exceções após a destruição de objetos

Outra maneira de manipular exceções é passá-los para o contexto de manipulação de exceção externo Avançar.No seu catch bloco, você pode fazer uma limpeza de seus objetos alocados localmente e, em seguida, lançar a exceção para processamento adicional.

A função throwing pode ou não precise desalocar objetos de heap.Se a função sempre desaloca o objeto da heap antes de retornar caso normal, em seguida, a função deve também desalocar o objeto da heap antes de lançar a exceção.Por outro lado, se a função normalmente não desalocar o objeto antes de retornar caso normal, em seguida, você deve decidir em cada caso, se o objeto de heap deve ser desalocado.

A exemplo a seguir mostra como localmente alocados objetos pode 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 de quadro; também é chamado de destruidor do objeto quadro.

Se você chamar funções que podem lançar exceções, você pode usar try/catch blocos para certificar-se de capturar exceções e ter a chance de destruir os objetos que você criou.Em particular, esteja ciente de que muitas funções do MFC podem lançar exceções.

Para obter mais informações, consulte exceções: detectar e excluir exceções.

Consulte também

Conceitos

Tratamento de exceção no MFC