Maîtriser la gestion d'exceptions en C++ : Exemples pratiques try, catch, throw
Qu'est-ce que la gestion d'exceptions en C++ ?
La gestion d'exceptions permet aux programmes C++ de récupérer gracieusement des erreurs d'exécution inattendues. Lorsqu'une erreur se produit, le contrôle saute vers un gestionnaire spécial qui peut décider comment réagir.
En enfermant le code potentiellement problématique dans un bloc try suivi d'une ou plusieurs clauses catch, vous donnez au programme un chemin clair pour gérer les conditions exceptionnelles.
Si aucune exception n'est levée, le bloc try s'exécute normalement et les gestionnaires sont ignorés.
Dans ce tutoriel, vous apprendrez :
- Ce qu'est la gestion d'exceptions et pourquoi elle est importante
- Les mots-clés de base :
throw,catch,try - Syntaxe et motifs courants
- Exceptions standard définies par la bibliothèque standard C++
- Comment créer et utiliser des exceptions définies par l'utilisateur
Pourquoi la gestion d'exceptions ?
La gestion d'exceptions offre plusieurs avantages tangibles :
- Sépare la logique de gestion d'erreurs du code régulier, améliorant la lisibilité et la maintenabilité.
- Permet aux fonctions d'exposer uniquement les exceptions qui les concernent ; les appelants peuvent gérer le reste.
Mots-clés clés de la gestion d'exceptions
Trois mots-clés forment l'épine dorsale de la gestion d'exceptions en C++ :
- throw – signale une condition d'erreur en créant un objet d'exception.
- catch – intercepte une exception et fournit le code pour y réagir.
- try – marque la région de code qui peut lever des exceptions.
Le code à l'intérieur du bloc try est appelé code protégé ; s'il lève une exception, le bloc catch correspondant est exécuté.
Syntaxe
try {
// code protégé
} catch (Exception_Name exception1) {
// gérer exception1
} catch (Exception_Name exception2) {
// gérer exception2
} // ... plus de blocs catch
- Un seul
trypeut être suivi de plusieurs clausescatch. - Le type dans chaque clause
catchspécifie l'exception à intercepter. - À l'intérieur d'un
catch, l'exception interceptée peut être référencée par l'identificateur choisi.
Exemple 1 : Accès à un élément de vector hors limites
#include<iostream>
#include<vector>
using namespace std;
int main() {
vector<int> vec;
vec.push_back(0);
vec.push_back(1);
try {
vec.at(2); // hors limites
} catch (exception& ex) {
cout << "Exception occurred!" << endl;
}
return 0;
}
Sortie :

Voici une capture d'écran du code :

Décomposition du code :
- Inclure
iostreametvectorpour les E/S et le support de conteneur. - Utiliser l'espace de noms
stdpour éviter les noms pleinement qualifiés. - Instancier un
vector<int>et le peupler. - Tenter d'accéder à un élément au-delà des limites du vector dans un bloc
try. - Intercepter l'exception standard
std::exceptionet afficher un message. - Retourner depuis
main.
Exemple 2 : Gestion de la division par zéro
#include <iostream>
using namespace std;
double zeroDivision(int x, int y) {
if (y == 0) {
throw "Division by Zero!";
}
return static_cast<double>(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;
}
Sortie :

Voici une capture d'écran du code :

Décomposition du code :
- Définir
zeroDivisionqui lève une chaîne C quand on divise par zéro. - Appeler la fonction dans un bloc
tryet afficher le résultat. - Intercepter l'exception de type chaîne et afficher un message d'erreur.
Exceptions standard C++

La bibliothèque standard déclare une riche hiérarchie d'exceptions dans <exception>. Voici les plus fréquemment utilisées :
| Exception | Description |
|---|---|
| std::exception | Classe de base pour toutes les exceptions standard. |
| std::bad_alloc | Levée par new en cas d'échec d'allocation. |
| std::bad_cast | Levée par dynamic_cast quand un cast échoue. |
| std::bad_exception | Utilisée pour signaler une exception inattendue. |
| std::bad_typeid | Levée par typeid sur un glvalue de type polymorphe qui est nul. |
| std::logic_error | Erreurs détectables par le programmeur. |
| std::domain_error | Domaine invalide pour une fonction mathématique. |
| std::invalid_argument | Fonction a reçu un argument invalide. |
| std::length_error | Tentative de créer une chaîne trop grande. |
| std::out_of_range | Levée par vector::at quand l'index est hors limites. |
| std::runtime_error | Erreurs d'exécution non capturées par d'autres catégories. |
| std::overflow_error | Débordement mathématique survenu. |
| std::range_error | Valeur hors plage pour l'opération. |
| std::underflow_error | Sous-débordement mathématique survenu. |
Exceptions définies par l'utilisateur
La classe de base std::exception peut être étendue pour créer des types d'erreur spécifiques au domaine. La redéfinition de what() fournit un message descriptif.
Exemple : Exception personnalisée
#include <iostream>
#include <exception>
using namespace std;
class NewException : public exception {
public:
const char* what() const noexcept override {
return "newException occurred";
}
} newex;
int main() {
try {
throw newex;
} catch (exception& ex) {
cout << ex.what() << '\n';
}
return 0;
}
Sortie :

Voici une capture d'écran du code :

Décomposition du code :
- Dériver
NewExceptiondestd::exceptionet redéfinirwhat(). - Instancier un objet
newexà lever. - Lever
newexdans un bloctry. - Intercepter par référence vers
std::exceptionet afficher le message viawhat().
À retenir
- La gestion d'exceptions est essentielle pour des applications C++ robustes qui doivent récupérer des erreurs d'exécution.
- Utilisez
trypour protéger le code,catchpour répondre, etthrowpour signaler les problèmes. - Tirez parti du riche ensemble d'exceptions standard, et étendez
std::exceptionquand des types d'erreur personnalisés sont nécessaires. - Gardez la logique de gestion d'erreurs séparée de la logique métier pour un code plus propre et maintenable.
Langue C
- Commentaires C++ : Bonnes pratiques pour un code lisible et maintenable
- Maîtriser la gestion d'exceptions Python : try, except, else et finally expliqués
- Maîtriser la gestion d'exceptions Java : try, catch, finally, throw et throws expliqués
- Maîtriser la gestion d'exceptions Java : try, catch, finally et ressources
- Maîtriser le switch-case en C++ : Syntaxe, utilisation et exemples pratiques
- Maîtriser l'allocation de tableaux dynamiques en C++ : Guide pratique avec exemples de code
- Les structures en C++ expliquées avec un exemple pratique
- Maîtriser std::list en C++ : Syntaxe, Fonctions et Exemples Pratiques
- Struct vs Class en C++ : Différences Clés, Syntaxe et Cas d'Utilisation Optimaux