Instruções try, throw e catch (C++)

Para implementar o tratamento de exceções em C++, você usa as expressões try, throw e catch.

Primeiro, use um bloco try para incluir uma ou mais instruções que possam lançar uma exceção.

Uma expressão throw sinaliza que uma condição excepcional – geralmente, um erro – ocorreu em um bloco try. Você pode usar um objeto de qualquer tipo como o operando de uma expressão throw. Normalmente, esse objeto é usado para passar informações sobre o erro. Na maioria dos casos, recomendamos que você use a std::exception classe ou uma das classes derivadas definidas na biblioteca padrão. Se um deles não for apropriado, recomendamos que você derive sua própria classe de exceção do std::exception.

Para tratar as exceções que podem ser lançadas, implemente um ou vários blocos catch imediatamente depois de um bloco try. Cada bloco catch especifica o tipo de exceção que ele pode tratar.

Este exemplo mostra um bloco try e seus manipuladores. Suponhamos que GetNetworkResource() adquira dados por uma conexão de rede e que os dois tipos de exceções sejam classes definidas pelo usuário que derivam de std::exception. Observe que as exceções são capturadas pela referência const na instrução catch. Recomendamos que você lance exceções por valor e captura-as pela referência const.

Exemplo

MyData md;
try {
   // Code that could throw an exception
   md = GetNetworkResource();
}
catch (const networkIOException& e) {
   // Code that executes when an exception of type
   // networkIOException is thrown in the try block
   // ...
   // Log error message in the exception object
   cerr << e.what();
}
catch (const myDataFormatException& e) {
   // Code that handles another exception type
   // ...
   cerr << e.what();
}

// The following syntax shows a throw expression
MyData GetNetworkResource()
{
   // ...
   if (IOSuccess == false)
      throw networkIOException("Unable to connect");
   // ...
   if (readError)
      throw myDataFormatException("Format error");
   // ...
}

Comentários

O código após a cláusula try é a seção de código protegida. A expressão throwlança – ou seja, gera – uma exceção. O bloco de código após a cláusula catch é o manipulador de exceções. Esse é o manipulador que captura a exceção que é lançada quando os tipos nas expressões throw e catch são compatíveis. Para obter uma lista de regras que regem a correspondência de tipo em blocos catch, confira Como os blocos catch são avaliados. Se a instrução catch especificar reticências (...) em vez de um tipo, o bloco catch tratará todo tipo de exceção. Quando você compila com a opção, elas podem incluir exceções estruturadas /EHa em C e exceções assíncronas geradas pelo sistema ou pelo aplicativo, como proteção de memória, divisão por zero e violações de ponto flutuante. Como os blocos catch são processados na ordem do programa para localizar um tipo compatível, um manipulador de reticências deve ser o último manipulador para o bloco try associado. Use catch(...) com cuidado: não permita que um programa continue, a menos que o bloco de captura saiba como lidar com a exceção específica que é capturada. Normalmente, um bloco catch(...) é usado para registrar erros e executar a limpeza especial antes de execução do programa ser interrompida.

Uma throw expressão que não tem operando relança a exceção que está sendo manipulada no momento. Recomendamos esse formulário ao relançar a exceção, pois isso preserva as informações de tipo polimórfico da exceção original. Essa expressão deve ser usada somente em um manipulador catch ou em uma função que é chamada por um manipulador catch. O objeto de exceção relançado é o objeto de exceção original, não uma cópia.

try {
   throw CSomeOtherException();
}
catch(...) {
   // Catch all exceptions - dangerous!!!
   // Respond (perhaps only partially) to the exception, then
   // re-throw to pass the exception to some other handler
   // ...
   throw;
}

Confira também

Práticas recomendadas do C++ modernas para tratamento de erros e exceções
Palavras-chave
Exceções C++ não tratadas
__uncaught_exception