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.