Compartilhar via


Exceções: alterações feitas em macros de exceção na versão 3.0

Este é um tópico avançada.

MFC na versão 3,0 e posterior, as macros manipulação de exceções gerais foram modificados para usar exceções C++. Este artigo informa como essas alterações podem afetar o comportamento de código existente que usa macros.

Este artigo abrange os seguintes tópicos:

  • Tipos de exceção e a macro CATCH

  • Lançando exceções

Tipos de exceção e a macro CATCH

Em versões anteriores de MFC, a macro de CATCH usou as informações de tipo de tempo de execução MFC para determinar um tipo de exceção; o tipo de exceção é determinado, ou está no site de captura. Com exceções C++, porém, o tipo de exceção sempre é determinada no site de lançamento pelo tipo de objeto de exceção que é lançada. Isso causará incompatibilidades em casos raros onde o tipo de ponteiro para um objeto é diferente do tipo de objeto lançado.

O exemplo a seguir ilustra ao resultado dessa diferença entre a versão 3,0 MFC o 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

Esse código se comporta de maneira diferente na versão 3,0 porque o controle passa sempre o primeiro bloco de catch com exceções gerais uma declaração de correspondência. O resultado da expressão do lançamento

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

é gerado como CException*, mesmo que é criado como CCustomException. A macro de CATCH nas versões 2,5 MFC e no anteriores CObject::IsKindOf testar em tempo de execução do tipo. Como a expressão

e->IsKindOf(RUNTIME_CLASS(CException));

forem verdadeiras, as primeiras captura do bloco de captura a exceção. Na versão 3,0, que usa exceções C++ para implementar vários macros manipulação de exceções gerais, o segundo bloco de captura corresponde CExceptionlançado.

O código como isso é raro. Normalmente aparece quando um objeto de exceção é passado para outra função que aceita **CException***genérico, executa o processamento de “previamente geram”, e finalmente gerou a exceção.

Para resolver esse problema, mova a expressão do lançamento da função ao código de chamada e gerar uma exceção do tipo real conhecido do compilador a exceção é gerada.

Lançando exceções

Um bloco de captura não pode gerar o mesmo ponteiro de exceção que capturou.

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

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

Usar THROW no bloco de captura faz com que o ponteiro e a ser excluído, de modo que o site externo de captura recebe um ponteiro inválido. Use o novo elançamento de THROW_LAST .

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

Consulte também

Conceitos

Tratamento de exceções em MFC