Carregando...

Tratamento de exceções

O tratamento de exceções em C++ é um mecanismo fundamental que permite às aplicações lidarem com situações inesperadas durante a execução, como divisão por zero, acesso a índices inválidos ou falhas de alocação de memória. Utilizar exceções corretamente garante que o fluxo normal da aplicação seja separado da lógica de erro, melhorando a manutenção, legibilidade e robustez do código.
Em C++, o tratamento de exceções é realizado com as palavras-chave try, catch e throw. O bloco try contém o código que pode gerar uma exceção, throw é usado para lançar a exceção, e catch captura e trata a exceção lançada. Essa abordagem evita que erros não tratados provoquem falhas na aplicação e facilita a recuperação de erros de forma controlada.
Durante este tutorial, você aprenderá a utilizar tanto exceções padrão da biblioteca C++ quanto exceções personalizadas. Além disso, serão explorados conceitos avançados, como RAII (Resource Acquisition Is Initialization) para gerenciamento automático de recursos, integração com princípios de programação orientada a objetos e práticas para construir aplicações robustas e seguras. Compreender o tratamento de exceções é essencial em projetos complexos e arquiteturas de software onde confiabilidade e manutenção são críticas.

Exemplo Básico

text
TEXT Code
\#include <iostream>
\#include <stdexcept>

int dividir(int a, int b) {
if (b == 0) {
throw std::invalid_argument("Divisão por zero não é permitida.");
}
return a / b;
}

int main() {
int x = 10;
int y = 0;

try {
int resultado = dividir(x, y);
std::cout << "Resultado: " << resultado << std::endl;
} catch (const std::invalid_argument& e) {
std::cerr << "Erro: " << e.what() << std::endl;
}

std::cout << "Programa continua executando após o tratamento da exceção." << std::endl;
return 0;

}

No exemplo acima, a função dividir verifica se o divisor é zero e lança uma exceção std::invalid_argument quando necessário. O bloco try em main chama a função e, caso ocorra a exceção, o bloco catch captura o erro.
O uso de const std::invalid_argument& evita cópia desnecessária do objeto de exceção, mantendo a integridade do tipo da exceção. O método e.what() retorna a mensagem de erro associada. Esse padrão separa a lógica de erro da execução normal, garantindo que o programa continue funcionando de maneira controlada mesmo após a ocorrência de um erro. Essa prática é especialmente importante em sistemas críticos, aplicações de grande escala e em código orientado a objetos que requer robustez e manutenção fácil.

Exemplo Prático

text
TEXT Code
\#include <iostream>
\#include <vector>
\#include <stdexcept>

class VetorSeguro {
private:
std::vector<int> dados;
public:
void adicionar(int valor) {
dados.push_back(valor);
}

int obter(size_t indice) const {
if (indice >= dados.size()) {
throw std::out_of_range("Índice fora do limite do vetor.");
}
return dados[indice];
}

};

int main() {
VetorSeguro vetor;
vetor.adicionar(5);
vetor.adicionar(10);

try {
std::cout << "Elemento 0: " << vetor.obter(0) << std::endl;
std::cout << "Elemento 2: " << vetor.obter(2) << std::endl;
} catch (const std::out_of_range& e) {
std::cerr << "Exceção capturada: " << e.what() << std::endl;
} catch (const std::exception& e) {
std::cerr << "Exceção geral: " << e.what() << std::endl;
}

std::cout << "Programa continua executando após o tratamento das exceções." << std::endl;
return 0;

}

No exemplo prático, a classe VetorSeguro encapsula um std::vector padrão e fornece um método seguro obter que lança uma exceção std::out_of_range se o índice fornecido for inválido. O main demonstra a captura específica da exceção out_of_range antes de capturar exceções mais gerais, garantindo tratamento adequado e detalhado.
Esse padrão mostra princípios de orientação a objetos, encapsulamento de dados e construção de APIs seguras. Em aplicações reais, especialmente em sistemas de larga escala ou multithreaded, o tratamento correto de exceções é essencial para prevenir falhas, vazamentos de memória e manter a integridade dos dados.

Boas práticas em C++ para tratamento de exceções incluem: capturar exceções por referência para preservar informações do tipo derivado, utilizar exceções padrão quando possível, gerenciar recursos automaticamente via RAII, e estruturar blocos try/catch adequadamente para minimizar o impacto na performance.
Erros comuns incluem: lançar exceções para fluxo normal de execução, capturar exceções em nível inadequado, e capturar por valor, causando cópia desnecessária. Para funções críticas de desempenho, recomenda-se usar noexcept. Ferramentas como AddressSanitizer e warnings do compilador ajudam na detecção de problemas. Mensagens de erro não devem expor dados sensíveis.

📊 Tabela de Referência

C++ Element/Concept Description Usage Example
try Bloco de código que pode gerar exceção try { /* código */ }
catch Bloco que captura exceção catch (const std::exception& e) { /* tratamento */ }
throw Lança uma exceção throw std::runtime_error("Erro");
std::exception Classe base para exceções padrão catch (const std::exception& e) { std::cerr << e.what(); }
RAII Gerencia recursos automaticamente std::unique_ptr<int> ptr(new int(5));
noexcept Indica que função não lança exceções void func() noexcept { /* código */ }

O tratamento de exceções em C++ é essencial para desenvolver aplicações confiáveis e de fácil manutenção. O domínio de try, catch, throw, RAII, exceções padrão e noexcept permite criar sistemas seguros, resilientes e fáceis de debugar.
Esses conhecimentos se conectam diretamente com gerenciamento de recursos, princípios de orientação a objetos e design seguro de algoritmos. Próximos passos incluem estudo de exceções em ambientes multithread, hierarquias personalizadas de exceções e otimização de performance com noexcept. Documentação oficial e livros especializados podem aprofundar o aprendizado e melhorar a prática em projetos reais.

🧠 Teste Seu Conhecimento

Pronto para Começar

Test Your Knowledge

Test your understanding of this topic with practical questions.

3
Perguntas
🎯
70%
Para Passar
♾️
Tempo
🔄
Tentativas

📝 Instruções

  • Leia cada pergunta cuidadosamente
  • Selecione a melhor resposta para cada pergunta
  • Você pode refazer o quiz quantas vezes quiser
  • Seu progresso será mostrado no topo