Gestion des exceptions en POO
Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy. Leçon 81 sur 104.
La gestion des exceptions en C++ fournit une manière structurée de détecter les erreurs d’exécution et d’y répondre. En programmation orientée objet, les exceptions s’intègrent naturellement aux hiérarchies de classes, ce qui vous permet de créer des types d’erreur pertinents qui fournissent un contexte sur ce qui s’est mal passé.
Le mécanisme de base utilise trois mots-clés : try, throw et catch. Le code susceptible d’échouer est placé dans un bloc try, les erreurs sont signalées avec throw, et les blocs catch gèrent des types d’exceptions spécifiques :
#include <iostream>
#include <stdexcept>
class BankAccount {
double balance;
public:
BankAccount(double b) : balance(b) {}
void withdraw(double amount) {
if (amount > balance) {
throw std::runtime_error("Insufficient funds");
}
balance -= amount;
}
double getBalance() const { return balance; }
};
int main() {
BankAccount account(100.0);
try {
account.withdraw(150.0);
} catch (const std::runtime_error& e) {
std::cout << "Error: "lt;< e.what() << "\n";
}
std::cout << "Balance: " << account.getBalance() << "\n";
}La bibliothèque standard C++ fournit une hiérarchie de classes d’exceptions ayant std::exception comme classe racine. Les classes dérivées courantes comprennent std::runtime_error pour les problèmes d’exécution et std::logic_error pour les erreurs de programmation. Toutes les exceptions standard fournissent une méthode what() qui renvoie un message d’erreur.
Lorsqu’une exception est levée, la pile se déroule : les destructeurs sont appelés pour tous les objets locaux tandis que le programme recherche un bloc catch correspondant. Cela garantit un nettoyage approprié même lorsque des erreurs surviennent, ce qui explique pourquoi RAII et la gestion des exceptions fonctionnent si bien ensemble.
Défi
FacileConstruisons une calculatrice de division sûre qui démontre la gestion des exceptions dans un contexte orienté objet. Vous allez créer une classe Calculator qui effectue des opérations de division et lève des exceptions explicites lorsqu'un problème survient, puis gérer ces exceptions correctement dans votre programme principal.
Vous allez organiser votre code sur trois fichiers :
Calculator.h: définissez votre classeCalculatorqui effectue des opérations mathématiques avec une gestion appropriée des erreurs.Votre
Calculatordoit disposer d'une méthodedivide(double numerator, double denominator)qui renvoie le résultat de la division. Cependant, si le dénominateur est nul, elle doit lever unestd::runtime_erroravec le messageDivision by zero. Si le numérateur ou le dénominateur est négatif, elle doit lever unestd::invalid_argumentavec le messageNegative values not allowed.Incluez également une méthode
safeSqrt(double value)qui renvoie la racine carrée de la valeur. Si la valeur est négative, levez unestd::runtime_erroravec le messageCannot compute square root of negative number. Vous devrez inclure<cmath>pour utiliser la fonctionsqrt.Calculator.cpp: implémentez les méthodes déclarées dans votre fichier d'en-tête. Veillez à inclure les en-têtes nécessaires (<stdexcept>et<cmath>) et à vérifier les conditions avant d'effectuer les opérations.main.cpp: lisez trois entrées (chacune sur une ligne distincte) :- Type d'opération : soit
divide, soitsqrt - Premier nombre (double)
- Deuxième nombre (double) : utilisé uniquement pour la division, ignoré pour sqrt
Créez un objet
Calculatoret effectuez l'opération demandée dans un bloc try. Si l'opération réussit, affichezResult: [value]. Si une exception est interceptée, affichezError: [message], où le message provient de la méthodewhat()de l'exception.Après le bloc try-catch (qu'une exception se soit produite ou non), affichez
Calculation completepour montrer que le programme continue son exécution après la gestion des exceptions.- Type d'opération : soit
Par exemple, avec les entrées divide, 10 et 2 :
Result: 5
Calculation completeAvec les entrées divide, 10 et 0 :
Error: Division by zero
Calculation completeAvec les entrées divide, -5 et 2 :
Error: Negative values not allowed
Calculation completeAvec les entrées sqrt, 16 et 0 :
Result: 4
Calculation completeAvec les entrées sqrt, -9 et 0 :
Error: Cannot compute square root of negative number
Calculation completeRemarquez comment le programme gère correctement les erreurs en interceptant les exceptions et en affichant des messages explicites, puis poursuit son exécution. Ce modèle permet de conserver une gestion des erreurs claire et de garder votre logique principale concentrée sur le chemin nominal.
Essayez vous-même
#include <iostream>
#include <string>
#include "Calculator.h"
using namespace std;
int main() {
// Lire les entrées
string operation;
double num1, num2;
cin >> operation;
cin >> num1;
cin >> num2;
// Créer un objet Calculator
Calculator calc;
// TODO: Utiliser un bloc try-catch pour effectuer l'opération
// - Si operation est "divide", appeler calc.divide(num1, num2)
// - Si operation est "sqrt", appeler calc.safeSqrt(num1)
// - En cas de succès, afficher "Result: " suivi du résultat
// - Capturer les exceptions et afficher "Error: " suivi du message d'exception (utiliser what())
// - After the try-catch, always print "Calculation complete"
return 0;
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesGénération et compilation en C++Fichiers d’en-tête et fichiers sourceEspaces de noms et portéeIntroduction à la POO en C++Classes et objetsLe pointeur « this »Méthodes (fonctions membres)Attributs (membres de données)Bases des constructeurs et destructeursRécapitulatif - Calculatrice simple4Propriétés de classe
Membres d’instance et statiquesAccesseurs et mutateursFonctions membres constMot-clé mutableMéthodes et variables statiquesFonctions et classes amiesRécapitulatif - Gestionnaire de compte bancaire7Héritage
Héritage de baseNiveaux d’accès de l’héritageOrdre d’appel des constructeurs et destructeursRedéfinition des méthodesFonctions virtuelles et VTableHéritage multipleHéritage virtuelRécapitulatif : hiérarchie des employés10Vue d’ensemble de la STL
Vue d’ensemble et philosophie de la STLConteneurs de la STLItérateursAlgorithmes de la STLFoncteurs et expressions lambdaRécapitulatif - fréquence des mots13Modèles de conception, partie 1
Introduction aux modèles de conceptionModèle SingletonFabrique et fabrique abstraiteModèle BuilderModèle ObserverModèle Strategy2Gestion de la mémoire
Mémoire de pile ou de tasPointeurs et référencesMémoire dynamique (new/delete)Pointeurs intelligents en C++RAII en C++Récapitulatif - Gestionnaire de tableaux dynamiques5Encapsulation
Spécificateurs d’accès en C++Spécificateurs d’accès en profondeurMasquage de l’informationStruct vs classeClasses imbriquées et internesRécapitulatif - Système de gestion des dossiers étudiants8Polymorphisme
Polymorphisme à la compilation vs à l’exécutionSurcharge de fonctionsRetour sur les fonctions virtuellesFonctions virtuelles puresClasses abstraitesConception d’interfaces en C++Conversion dynamique et RTTIRécapitulatif - Calculateur de formes11Concepts avancés de la POO
Composition ou héritageMixins via CRTPIdiom PimplEffacement de typeClasses enum et typage fortGestion des exceptions en POOHiérarchies d’exceptions personnalisées3Constructeurs et destructeurs
Constructeur par défautConstructeur paramétréConstructeur de copieConstructeur de déplacementListes d’initialisation des constructeursConstructeurs déléguésApprofondissement des destructeursRègle des trois / cinq / zéroRécapitulatif - Classe String6Surcharge des opérateurs
Introduction à la surcharge des opérateursSurcharge des opérateurs arithmétiquesSurcharge des opérateurs de comparaisonOpérateurs de fluxSurcharge de l’opérateur d’affectationSurcharge des opérateurs [] et ()Opérateurs de conversion de typeRécapitulatif – Classe Matrix9Templates
Templates de fonctionsTemplates de classesSpécialisation des templatesTemplates variadiquesBases de SFINAE et des traits de typesRécapitulatif - Conteneur génériqueEntraînez-vous par vous-même : Compilateur C++ en ligne