Dominando Tratamento de Exceções em C++: Guia Completo
Uma exceção é um problema que surge durante a execução de um programa. Uma exceção C++ é uma resposta a uma circunstância excepcional que surge enquanto um programa está rodando, como uma tentativa de divisão por zero.
Exceções fornecem uma forma de transferir controle de uma parte do programa para outra. Tratamento de exceções em C++ é construído sobre três palavras-chave: try, catch e throw.
throw — Um programa lança uma exceção quando um problema aparece. Isso é feito usando a palavra-chave throw.
catch — Um programa captura uma exceção com um manipulador de exceção no local do programa onde você quer lidar com o problema. A palavra-chave catch indica a captura de uma exceção.
try — Um bloco try identifica um bloco de código para o qual exceções particulares serão ativadas. É seguido por um ou mais blocos catch.
Assumindo que um bloco levantará uma exceção, um método captura uma exceção usando uma combinação das palavras-chave try e catch. Um bloco try/catch é colocado ao redor do código que pode gerar uma exceção. Código dentro de um bloco try/catch é referido como código protegido, e a sintaxe para usar try/catch é a seguinte:
try {
// código protegido
} catch(ExceptionName e1) {
// bloco catch
} catch(ExceptionName e2) {
// bloco catch
} catch(ExceptionName eN) {
// bloco catch
}
Você pode listar múltiplas instruções catch para capturar diferentes tipos de exceções caso seu bloco try levante mais de uma exceção em situações diferentes.
Lançando Exceções
Exceções podem ser lançadas em qualquer lugar dentro de um bloco de código usando a instrução throw. O operando da instrução throw determina um tipo para a exceção e pode ser qualquer expressão e o tipo do resultado da expressão determina o tipo de exceção lançada.
O exemplo a seguir lança uma exceção quando ocorre condição de divisão por zero:
double division(int a, int b) {
if(b == 0) {
throw "Division by zero condition!";
}
return (a/b);
}
Capturando Exceções
O bloco catch seguinte ao bloco try captura qualquer exceção. Você pode especificar que tipo de exceção quer capturar e isso é determinado pela declaração de exceção que aparece entre parênteses após a palavra-chave catch.
try {
// código protegido
} catch(ExceptionName e) {
// código para lidar com exceção ExceptionName
}
O código acima captura uma exceção do tipo ExceptionName. Se você quiser especificar que um bloco catch deve lidar com qualquer tipo de exceção lançada em um bloco try, deve colocar reticências, ..., entre os parênteses envolvendo a declaração de exceção da seguinte forma:
try {
// código protegido
} catch(...) {
// código para lidar com qualquer exceção
}
O exemplo a seguir lança uma exceção de divisão por zero e a captura no bloco catch:
#include <iostream>
using namespace std;
double division(int a, int b) {
if(b == 0) {
throw "Division by zero condition!";
}
return (a/b);
}
int main() {
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
} catch(const char* msg) {
cerr << msg << endl;
}
return 0;
}
Como estamos levantando uma exceção do tipo const char*, ao capturar esta exceção, temos que usar const char* no bloco catch. Se compilarmos e executarmos o código acima, produzirá o seguinte resultado:
Division by zero condition!
Exceções Padrão do C++
C++ fornece uma lista de exceções padrão definidas em <exception> que podemos usar em nossos programas. Estas são organizadas em uma hierarquia de classes pai-filho mostrada abaixo:
Aqui está a pequena descrição de cada exceção mencionada na hierarquia acima:
| Nº | Exceção e Descrição |
|---|---|
| 1 | std::exception Uma exceção e classe pai de todas as exceções padrão C++. |
| 2 | std::bad_alloc Pode ser lançada por new. |
| 3 | std::bad_cast Pode ser lançada por dynamic_cast. |
| 4 | std::bad_exception Dispositivo útil para lidar com exceções inesperadas em programa C++. |
| 5 | std::bad_typeid Pode ser lançada por typeid. |
| 6 | std::logic_error Exceção que teoricamente pode ser detectada lendo o código. |
| 7 | std::domain_error Exceção lançada quando domínio matematicamente inválido é usado. |
| 8 | std::invalid_argument Lançada devido a argumentos inválidos. |
| 9 | std::length_error Lançada quando uma std::string muito grande é criada. |
| 10 | std::out_of_range Pode ser lançada pelo método 'at', ex: std::vector e std::bitset<>::operator[](). |
| 11 | std::runtime_error Exceção que teoricamente não pode ser detectada lendo o código. |
| 12 | std::overflow_error Lançada se overflow matemático ocorre. |
| 13 | std::range_error Ocorre quando você tenta armazenar valor fora do intervalo. |
| 14 | std::underflow_error Lançada se underflow matemático ocorre. |
Definindo Novas Exceções
Você pode definir suas próprias exceções herdando e sobrescrevendo funcionalidade da classe exception. O exemplo a seguir mostra como você pode usar a classe std::exception para implementar sua própria exceção de forma padrão:
#include <iostream>
#include <exception>
using namespace std;
struct MyException : public exception {
const char* what() const throw() {
return "C++ Exception";
}
};
int main() {
try {
throw MyException();
} catch(MyException& e) {
std::cout << "MyException caught" << std::endl;
std::cout << e.what() << std::endl;
} catch(std::exception& e) {
// Outros erros
}
}
Isso produziria o seguinte resultado:
MyException caught C++ Exception
Aqui, what() é um método público fornecido pela classe exception e foi sobrescrito por todas as classes filhas de exceção. Retorna a causa de uma exceção.
Linguagem C
- Dominando Operadores em C++: Guia Completo com Exemplos Práticos
- Comentários em C++: Boas Práticas para Código Legível e Manutenível
- Dominando Templates de Classe em C++: Um Guia Prático
- Manipulação de Arquivos em C: Dominando I/O com fopen, fprintf, fread e fseek
- Dominando Tratamento de Exceções em Java: Try, Catch, Finally, Throw e Throws Explicados
- Dominando Tratamento de Exceções em C++: Exemplos Práticos com Try, Catch, Throw
- Dominando Tratamento de Exceções em Python: Usando try, except, finally e raise Efetivamente
- Dominando Tratamento de Erros em C: Boas Práticas e Técnicas
- Linguagem de Programação C++: Visão Geral e Principais Características
- Constantes e Literais em C++: Tipos, Sintaxe e Boas Práticas