C++ Erros Intermediário
Exceções
Em C++, exceções são o mecanismo padrão para separar a detecção de um erro do seu tratamento. Quando algo dá errado, usamos throw para lançar um objeto; quem chamou pode capturá-lo com try/catch. Isso evita códigos de erro espalhados e permite que a pilha de chamadas seja desenrolada automaticamente, destruindo objetos locais (RAII).
A biblioteca padrão define a hierarquia std::exception com classes como std::runtime_error, std::logic_error e std::out_of_range. Capturar por referência (const std::exception&) evita slicing e permite acessar what(). Prefira lançar tipos que herdam de std::exception para interoperar com código genérico.
A palavra-chave noexcept promete que uma função não lança exceções. Se ela lançar, o programa chama std::terminate. Isso é essencial para destrutores, move constructors e operações usadas em containers, pois permite otimizações e garante segurança em situações de emergência.
Por fim, as garantias de exceção descrevem o que uma operação assegura se uma exceção for lançada: básica (nenhum recurso vaza, estado válido), forte (rollback atômico) e nothrow (nunca lança). Entender essas garantias ajuda a projetar código robusto e a documentar contratos.
Pontos-chave
throwlança um objeto;try/catchcaptura por tipo, preferencialmente por referência (const std::exception&).- A hierarquia
std::exceptionpadroniza erros; usestd::runtime_errorpara falhas de execução estd::logic_errorpara erros de programação. noexceptindica que uma função não lança; se lançar,std::terminateé chamado.- As garantias de exceção (básica, forte, nothrow) definem o estado do programa após uma falha.
- Destrutores e move constructors devem ser
noexceptpara segurança e desempenho.
#include <iostream>
#include <stdexcept>
#include <string>
// Função que pode lançar exceção
double divide(double a, double b) {
if (b == 0.0)
throw std::runtime_error("divisao por zero");
return a / b;
}
int main() {
try {
std::cout << "10 / 2 = " << divide(10, 2) << '\n';
std::cout << "10 / 0 = " << divide(10, 0) << '\n'; // lança
std::cout << "nunca chega aqui\n";
}
catch (const std::exception& e) {
std::cerr << "Erro capturado: " << e.what() << '\n';
}
std::cout << "Fim do programa.\n";
return 0;
}