Compartilhar via


Exceções: Alterações exceção Macros na versão 3.0

Este é um tópico avançado.

MFC versão 3.0 e posterior, as macros de manipulação de exceções foram alteradas para usar exceções do C++.Esse artigo informa como essas alterações podem afetar o comportamento do código existente que usa as macros.

Este artigo aborda os seguintes tópicos:

  • Tipos de exceção e a macro CATCH

  • Relançar exceções

Tipos de exceção e a macro CATCH

Em versões anteriores do MFC, o CATCH macro usada informações sobre o tipo de time de execução MFC para determinar o tipo da exceção; tipo da exceção é determinado, em outras palavras, no site catch.Com as exceções do C++, no entanto, tipo da exceção é sempre determinado no site throw pelo tipo do objeto de exceção é acionada.Isso fará com que incompatibilidades no caso raro onde o tipo de ponteiro para o objeto gerado difere do tipo de objeto gerado.

O exemplo a seguir ilustra a conseqüência essa diferença entre MFC versão 3.0 e versões anteriores:

TRY
{
   THROW( (CException*) new CCustomException() );
}
CATCH( CCustomException, e )
{
   TRACE( "MFC 2.x will land here\n" );
}
AND_CATCH( CException, e )
{
   TRACE( "MFC 3.0 will land here\n" );
}
END_CATCH

Se esse código comporta de forma diferente na versão 3.0 porque sempre passa o controle para o primeiro catch bloco com uma declaração de exceção correspondente.O resultado da expressão throw

THROW( (CException*) new CCustomException() );

é lançada sistema autônomo um CException *, mesmo que ela é construída sistema autônomo um CCustomException.The CATCH macro em MFC versões 2.5 e anteriores usa CObject::IsKindOf Para testar o tipo em time de execução. Porque a expressão

e->IsKindOf(RUNTIME_CLASS(CException));

é verdade, o primeiro bloco catch captura a exceção.Na versão 3.0, que usa as exceções do C++ para implementar várias das macros manipulação de exceção, o segundo capturar correspondências de bloco a geradas CException.

Código como este é incomum.Geralmente aparece quando um objeto de exceção é passado para outra função que aceita um genérico CException *, executa o processamento "pre-throw" e finalmente lança a exceção.

Para contornar esse problema, mova a expressão throw da função para o código de chamada e lançar uma exceção do tipo real conhecido para o compilador no time a exceção é gerada.

Re-Throwing exceções

Um bloco catch não pode lançar o ponteiro de exceção mesmo que ele detectado.

Por exemplo, esse código era válido nas versões anteriores, mas terá resultados inesperados com versão 3.0:

   TRY
   {
      // Do something to throw an exception.
      AfxThrowUserException();
   }
   CATCH( CException, e )
   {
      THROW( e );    // Wrong. Use THROW_LAST() instead
   }
   END_CATCH
}

Usando THROW no bloco catch faz com que o ponteiro e a ser excluído, para que o site externo catch irá receber um ponteiro inválido. Use THROW_LAST para relançar e.

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

Consulte também

Conceitos

Exceção Handling in MFC