Exceções: convertendo a partir de macros de exceção MFC
Esse é um tópico avançado.
Este artigo explica como converter código existente escrito com macros da Microsoft Foundation Class — TRY, CATCH, THROW e assim por diante — para usar as palavras-chave de tratamento de exceções de C++ try
, catch
e throw
. Os tópicos incluem:
Vantagens da conversão
Você provavelmente não precisa converter o código existente, embora deva estar ciente das diferenças entre as implementações de macro na versão 3.0 do MFC e as implementações em versões anteriores. Essas diferenças e alterações posteriores no comportamento do código são discutidas em Exceções: alterações nas macros de exceção na Versão 3.0.
Estas são as principais vantagens da conversão:
O código que usa as palavras-chave de tratamento de exceções de C++ é compilado para um .EXE ou .DLL ligeiramente menor.
As palavras-chave de tratamento de exceções de C++ são mais versáteis: elas podem tratar exceções de qualquer tipo de dados que possa ser copiado (
int
,float
,char
e assim por diante), enquanto as macros tratam exceções somente da classeCException
e de classes derivadas dela.
A principal diferença entre as macros e as palavras-chave é que o código que usa as macros exclui "automaticamente" uma exceção capturada quando a exceção sai do escopo. O código que usa palavras-chave não faz isso, portanto, você precisa excluir explicitamente uma exceção capturada. Para obter mais informações, confira o artigo Exceções: capturando e excluindo exceções.
Outra diferença é a sintaxe. A sintaxe de macros e palavras-chave difere em três aspectos:
Declarações de exceção e argumentos de macro:
Uma invocação de macro CATCH tem a seguinte sintaxe:
CATCH(exception_class, exception_object_pointer_name)
Observe a vírgula entre o nome da classe e o nome do ponteiro do objeto.
A declaração de exceção da palavra-chave
catch
usa esta sintaxe:catch(exception_typeexception_name)
Essa instrução de declaração de exceção indica o tipo de exceção de que o bloco catch trata.
Delimitação de blocos catch:
Com as macros, a macro CATCH (com seus argumentos) inicia o primeiro bloco catch; a macro AND_CATCH inicia os blocos catch subsequentes e a macro END_CATCH encerra a sequência de blocos catch.
Com as palavras-chave, a palavra-chave
catch
(com sua declaração de exceção) inicia cada bloco catch. Não há nenhum equivalente à macro END_CATCH; o bloco catch termina com sua chave de fechamento.A expressão throw:
As macros usam THROW_LAST para gerar novamente a exceção atual. A palavra-chave
throw
, sem argumento, tem o mesmo efeito.
Fazendo a conversão
Para converter código usando macros para usar as palavras-chave de tratamento de exceção de C++
Localize todas as ocorrências das macros MFC TRY, CATCH, AND_CATCH, END_CATCH, THROW e THROW_LAST.
Substitua ou exclua todas as ocorrências das seguintes macros:
TRY (substitua por
try
)CATCH (substitua por
catch
)AND_CATCH (substitua por
catch
)END_CATCH (exclua)
THROW (substitua por
throw
)THROW_LAST (substitua por
throw
)Modifique os argumentos de macro para que eles formem declarações de exceção válidas.
Por exemplo, alteração
CATCH(CException, e)
até
catch (CException* e)
Modifique o código nos blocos catch para que ele exclua objetos de exceção conforme necessário. Para obter mais informações, confira o artigo Exceções: capturando e excluindo exceções.
Aqui está um exemplo de código de tratamento de exceções usando macros de exceção do MFC. Observe que, como o código no seguinte exemplo usa as macros, a exceção e
é excluída automaticamente:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e)
{
if (m_bPassExceptionsUp)
THROW_LAST();
if (m_bReturnFromThisFunction)
return;
// Not necessary to delete the exception e.
}
END_CATCH
O código no próximo exemplo usa as palavras-chave de exceção de C++, portanto, a exceção deve ser excluída explicitamente:
try
{
// Do something to throw an exception.
AfxThrowUserException();
}
catch (CException* e)
{
if (m_bPassExceptionsUp)
throw;
if (m_bThrowDifferentException)
{
e->Delete();
throw new CMyOtherException;
}
if (m_bReturnFromThisFunction)
{
e->Delete();
return;
}
e->Delete();
}
Para obter mais informações, consulte Exceções: usando macros do MFC e exceções de C++.