Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Este é um tópico avançado.
No MFC versão 3.0 e posterior, as macros de tratamento de exceção foram alteradas para usar exceções C++. Este artigo explica 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
Em versões anteriores do MFC, a macro CATCH usava informações de tipo de tempo de execução MFC para determinar o tipo de exceção; o tipo de exceção é determinado, por outras palavras, no local de captura. Com exceções C++, no entanto, o tipo da exceção é sempre determinado no site de lançamento pelo tipo do objeto de exceção que é lançado. Isso causará incompatibilidades no caso raro em que o tipo do ponteiro para o objeto lançado difere do tipo do objeto lançado.
O exemplo a seguir ilustra a consequência dessa 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
Esse código se comporta de forma diferente na versão 3.0 porque o controle sempre passa para o primeiro catch bloco com uma declaração de exceção correspondente. O resultado da expressão de lançamento
THROW((CException*) new CCustomException());
é lançado como um CException*, embora seja construído como um CCustomException. A macro CATCH no MFC versões 2.5 e anteriores usa CObject::IsKindOf para testar o tipo em tempo de execução. Porque a expressão
e->IsKindOf(RUNTIME_CLASS(CException));
é verdade que o primeiro bloco de captura captura a exceção. Na versão 3.0, que usa exceções em C++ para implementar muitas das macros de tratamento de exceções, o segundo bloco catch corresponde ao lançado CException.
Código como este é incomum. Ele 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 lance uma exceção do tipo real conhecido pelo compilador no momento em que a exceção é gerada.
Re-Throwing Exceções
Um bloco de captura não pode lançar o mesmo apontador de exceção que capturou.
Por exemplo, este código era válido em 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 catch faz com que o ponteiro e seja excluído, para que o local de captura externo receba um ponteiro inválido. Use THROW_LAST para relançar e.
Para obter mais informações, consulte Exceções: capturando e excluindo exceções.