C++ Tratamento de exceções: exemplo Try, Catch, Throw
O que é tratamento de exceções C++?
Tratamento de exceções em C++ fornece uma maneira de lidar com circunstâncias inesperadas, como erros de tempo de execução. Assim, sempre que ocorre uma circunstância inesperada, o controle do programa é transferido para funções especiais conhecidas como manipuladores.
Para capturar as exceções, você coloca alguma seção do código sob inspeção de exceções. A seção de código é colocada dentro do bloco try-catch.
Se ocorrer uma situação excepcional nessa seção de código, uma exceção será lançada. Em seguida, o manipulador de exceções assumirá o controle do programa.
Caso não ocorra nenhuma circunstância excepcional, o código será executado normalmente. Os manipuladores serão ignorados.
Neste curso C++ tutorial, você aprenderá:
Por que tratamento de exceções?
Aqui estão os motivos para usar o Tratamento de Exceções em C++:
- Você separará seu código de tratamento de erros do seu código normal. O código será mais legível e mais fácil de manter.
- As funções podem lidar com as exceções que escolherem. Mesmo que uma função gere muitas exceções, ela tratará apenas algumas. O chamador tratará as exceções não detectadas.
Palavras-chave de tratamento de exceções
Tratamento de exceções em C++ gira em torno destas três palavras-chave:
- jogar– quando um programa encontra um problema, ele lança uma exceção. A palavra-chave throw ajuda o programa a realizar o lançamento.
- captura– um programa usa um manipulador de exceções para capturar uma exceção. Ele é adicionado à seção de um programa onde você precisa resolver o problema. Isso é feito usando a palavra-chave catch.
- tentar– o bloco try identifica o bloco de código para o qual determinadas exceções serão ativadas. Deve ser seguido por um/mais blocos catch.
Suponha que um bloco de código gere uma exceção. A exceção será capturada por um método usando palavras-chave try e catch. O bloco try/catch deve envolver o código que pode gerar uma exceção. Esse código é conhecido como código protegido.
Sintaxe
O try/catch usa esta sintaxe:
try { // the protected code } catch( Exception_Name exception1 ) { // catch block } catch( Exception_Name exception2 ) { // catch block } catch( Exception_Name exceptionN ) { // catch block }
- Embora tenhamos uma instrução try, podemos ter muitas instruções catch.
- O ExceptionName é o nome da exceção a ser capturada.
- A exceção1, exceção2 e exceçãoN são os nomes definidos para se referir às exceções.
1 exemplo:
#include<iostream> #include<vector> using namespace std; int main() { vector<int> vec; vec.push_back(0); vec.push_back(1); // access the third element, which doesn't exist try { vec.at(2); } catch (exception& ex) { cout << "Exception occurred!" << endl; } return 0; }
Saída:
Aqui está uma captura de tela do código:
Explicação do código:
- Inclua o arquivo de cabeçalho iostream no programa para usar seu funções.
- Inclua o arquivo de cabeçalho vetorial no programa para usar suas funções.
- Inclua o namespace std no programa em suas classes sem chamá-lo.
- Chame a função main(). A lógica do programa deve ser adicionada ao seu corpo.
- Crie um vetor chamado vec para armazenar dados inteiros.
- Adicione o elemento 0 ao vetor denominado vec.
- Adicione o elemento 1 ao vetor denominado vec.
- Um comentário. Será ignorado pelo C++ compilador.
- Use a instrução try para capturar uma exceção. O { marca o início do corpo do bloco try/catch. O código adicionado ao corpo se tornará o código protegido.
- Tente acessar o elemento armazenado no índice 2 (terceiro elemento) do vetor denominado vec. Este elemento não existe.
- Fim do corpo do bloco try/catch.
- Pegue a exceção. A mensagem de erro retornada será armazenada na variável ex.
- Imprima alguma mensagem no console se a exceção for detectada.
- Fim do corpo do bloco catch.
- O programa deve retornar um valor após a execução bem-sucedida.
- Fim do corpo da função main().
2 exemplo:
#include <iostream> using namespace std; double zeroDivision(int x, int y) { if (y == 0) { throw "Division by Zero!"; } return (x / y); } int main() { int a = 11; int b = 0; double c = 0; try { c = zeroDivision(a, b); cout << c << endl; } catch (const char* message) { cerr << message << endl; } return 0; }
Saída:
Aqui está uma captura de tela do código:
Explicação do código:
- Inclua o arquivo de cabeçalho iostream no programa para usar suas funções.
- Inclua o namespace std no programa em suas classes sem chamá-lo.
- Crie uma função chamada zeroDivision que receba dois argumentos inteiros, x e y. A função deve retornar um resultado duplo.
- Use uma instrução if para verificar se o valor do argumento da variável y é 0. O { marca o início do corpo if.
- A mensagem a ser retornada/lançada se y for 0.
- Fim do corpo da instrução if.
- A função zeroDivision deve retornar o valor de x/y.
- Fim do corpo da função zeroDivision.
- Chame o método main(). O { marca o início deste método.
- Declare uma variável inteira e atribua a ela o valor 11.
- Declare uma variável inteira b e atribua a ela o valor 0.
- Declare uma variável dupla c e atribua a ela o valor 0.
- Use a instrução try para capturar uma exceção. O { marca o início do corpo do bloco try/catch. O código adicionado ao corpo se tornará o código protegido.
- Chame a função zeroDivision e passe para os argumentos a e b, ou seja, 11 e 0. O resultado desta operação será armazenado na variável c.
- Imprima o valor da variável c no console.
- Fim do corpo do bloco try/catch.
- Pegue a exceção. A mensagem de erro retornada será armazenada na variável mensagem.
- Imprima a mensagem de erro retornada no console.
- Fim do corpo do bloco catch.
- O programa deve retornar um valor após a execução bem-sucedida.
- Fim do corpo da função main().
C++ Exceções padrão
C++ vem com uma lista de exceções padrão definidas em aula. Eles são descritos abaixo:
Exceção | Descrição |
---|---|
std::exceção | Esta é uma exceção e a classe pai de todos os padrões C++ exceções. |
std :: bad_alloc | Esta exceção é lançada por uma nova palavra-chave. |
std::bad_cast | Esta é uma exceção lançada por dynamic_cast. |
std::bad_exception | Um dispositivo útil para lidar com exceções inesperadas em C++ programas. |
std::bad_typeid | Uma exceção lançada por typeid. |
std::logic_error | Esta exceção é teoricamente detectável pela leitura do código. |
std::domain_error | Esta é uma exceção lançada após usar um domínio matematicamente inválido. |
std::argumento_inválido | Uma exceção lançada por usar argumentos inválidos. |
std::comprimento_erro | Uma exceção lançada após a criação de um grande std::string. |
std::out_of_range | Lançado pelo método at. |
std :: runtime_error | Esta é uma exceção que não pode ser detectada através da leitura do código. |
std::overflow_error | Esta exceção é lançada após a ocorrência de um estouro matemático. |
std::range_error | Esta exceção é lançada quando você tenta armazenar um valor fora do intervalo. |
std::underflow_error | Uma exceção lançada após a ocorrência de underflow matemático. |
Exceções definidas pelo usuário
O MVP da C++ A classe std::exception nos permite definir objetos que podem ser lançados como exceções. Esta classe foi definida no cabeçalho. A classe nos fornece uma função de membro virtual chamada what.
Esta função retorna uma sequência de caracteres terminada em nulo do tipo char *. Podemos sobrescrevê-lo em classes derivadas para ter uma descrição de exceção.
Exemplo:
#include <iostream> #include <exception> using namespace std; class newException : public exception { virtual const char* what() const throw() { return "newException occurred"; } } newex; int main() { try { throw newex; } catch (exception& ex) { cout << ex.what() << '\n'; } return 0; }
Saída:
Aqui está uma captura de tela do código:
Explicação do código:
- Inclua o arquivo de cabeçalho iostream em nosso programa. Usaremos suas funções sem erros.
- Inclua o arquivo de cabeçalho de exceção em nosso programa. Usaremos suas funções da mesma forma, sem erros.
- Inclua o namespace std em nosso programa para usar suas classes sem chamá-lo.
- Crie uma nova classe chamada newException. Esta classe herda a classe de exceção de C++.
- O início do corpo da classe.
- Substitua a função de membro virtual what() definida no arquivo de cabeçalho de exceção. Descreveremos então nossa própria exceção, a nova exceção.
- Inicie a definição da nova exceção.
- A mensagem a ser retornada se a nova exceção for detectada.
- Fim da definição da nova exceção.
- Fim do corpo da classe newException. O newex é o nome a ser usado para capturar nossa nova exceção, após a qual newException será chamada.
- Chame a função main(). A lógica do programa deve ser adicionada ao seu corpo. O { marca o início de seu corpo.
- Use uma instrução try para marcar o código dentro do qual precisamos marcar a exceção. O { marca o início do corpo do bloco try/catch. O código cercado por isso ficará protegido.
- Lance a exceção newex se for detectada.
- Fim do corpo de tentativa.
- Use a instrução catch para capturar a exceção. A mensagem de erro de exceção será armazenada na variável ex.
- Imprima a mensagem de erro de exceção no console.
- Fim do corpo da instrução catch.
- O programa deve retornar um valor se for executado com sucesso.
- Fim do corpo da função main().
Resumo
- Com tratamento de exceção em C++, você pode lidar com erros de tempo de execução.
- Erros de tempo de execução são os erros que ocorrem durante a execução do programa.
- O tratamento de exceções ajuda você a lidar com quaisquer circunstâncias inesperadas em seu programa.
- Quando ocorre uma circunstância inesperada, o controle do programa é transferido para manipuladores.
- Para capturar uma exceção, você coloca uma seção de código no bloco try-catch.
- A palavra-chave throw ajuda o programa a lançar exceções, ajudando o programa a lidar com o problema.
- A palavra-chave try ajuda a identificar o bloco de código para o qual determinadas exceções serão ativadas.
- Podemos sobrescrever a função what() do arquivo de cabeçalho de exceção para definir nossas exceções.