Compartilhar via


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 classe CException 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:

  1. 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.

  2. 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.

  3. 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++

  1. Localize todas as ocorrências das macros MFC TRY, CATCH, AND_CATCH, END_CATCH, THROW e THROW_LAST.

  2. 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)

  3. 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)
    
  4. 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++.

Confira também

Tratamento de exceção