Compartilhar via


Exceções: usando macros MFC e exceções do C++

Este artigo discute considerações sobre como escrever código que usa as macros de tratamento de exceções do MFC e as palavras-chave de tratamento de exceção do C++.

Este artigo aborda os seguintes tópicos:

Combinando palavras-chave de exceção e macros

Você pode misturar macros de exceção MFC e palavras-chave de exceção C++ no mesmo programa. Mas você não pode misturar macros MFC com palavras-chave de exceção C++ no mesmo bloco porque as macros excluem objetos de exceção automaticamente quando eles saem do escopo, enquanto o código que usa as palavras-chave de tratamento de exceção não. Para obter mais informações, consulte o artigo Exceções: Capturando e excluindo exceções.

A principal diferença entre as macros e as palavras-chave é que as macros "automaticamente" excluem uma exceção capturada quando a exceção sai do escopo. O código que usa as palavras-chave não; as exceções capturadas em um bloco catch devem ser excluídas explicitamente. A combinação de macros e palavras-chave de exceção C++ pode causar vazamentos de memória quando um objeto de exceção não é excluído ou corrupção de heap quando uma exceção é excluída duas vezes.

O código a seguir, por exemplo, invalida o ponteiro de exceção:

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

O problema ocorre porque e é excluído quando a execução é excluída do bloco CATCH "interno". Usar a macro THROW_LAST em vez da instrução THROW fará com que o bloco CATCH "externo" receba um ponteiro 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

Experimentar blocos dentro de blocos de captura

Você não pode relançar a exceção atual de dentro de um try bloco que está dentro de um bloco CATCH . O exemplo a seguir é invá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 obter mais informações, consulte Exceções: Examinando o conteúdo da exceção.

Consulte também

Tratamento de Exceções