Maîtriser la gestion des exceptions en C++ : Guide complet
Une exception est un problème qui survient pendant l'exécution d'un programme. Une exception C++ est une réponse à une circonstance exceptionnelle qui survient pendant l'exécution d'un programme, comme une tentative de division par zéro.
Les exceptions fournissent un moyen de transférer le contrôle d'une partie d'un programme à une autre. La gestion des exceptions en C++ repose sur trois mots-clés : try, catch et throw.
throw : Un programme lance une exception quand un problème se manifeste. Cela se fait en utilisant le mot-clé throw.
catch : Un programme attrape une exception avec un gestionnaire d'exception à l'endroit dans un programme où vous voulez gérer le problème. Le mot-clé catch indique la capture d'une exception.
try : Un bloc try identifie un bloc de code pour lequel des exceptions particulières seront activées. Il est suivi d'un ou plusieurs blocs catch.
En supposant qu'un bloc va lever une exception, une méthode attrape une exception en utilisant une combinaison des mots-clés try et catch. Un bloc try/catch est placé autour du code qui pourrait générer une exception. Le code dans un bloc try/catch est appelé code protégé, et la syntaxe pour utiliser try/catch est la suivante :
try {
// code protégé
} catch(ExceptionName e1) {
// bloc catch
} catch(ExceptionName e2) {
// bloc catch
} catch(ExceptionName eN) {
// bloc catch
}
Vous pouvez lister plusieurs instructions catch pour attraper différents types d'exceptions au cas où votre bloc try lèverait plus d'une exception dans différentes situations.
Lancer des exceptions
Les exceptions peuvent être lancées n'importe où dans un bloc de code en utilisant l'instruction throw. L'opérande de l'instruction throw détermine un type pour l'exception et peut être n'importe quelle expression et le type du résultat de l'expression détermine le type d'exception lancée.
Voici un exemple de lancement d'une exception lorsque la condition de division par zéro se produit :
double division(int a, int b) {
if(b == 0) {
throw "Condition division par zéro !";
}
return (a/b);
}
Attraper des exceptions
Le bloc catch suivant le bloc try attrape n'importe quelle exception. Vous pouvez spécifier quel type d'exception vous voulez attraper et cela est déterminé par la déclaration d'exception qui apparaît entre parenthèses après le mot-clé catch.
try {
// code protégé
} catch(ExceptionName e) {
// code pour gérer l'exception ExceptionName
}
Le code ci-dessus attrapera une exception de type ExceptionName. Si vous voulez spécifier qu'un bloc catch doit gérer n'importe quel type d'exception qui est lancé dans un bloc try, vous devez mettre une ellipse, ..., entre les parenthèses encadrant la déclaration d'exception comme suit :
try {
// code protégé
} catch(...) {
// code pour gérer n'importe quelle exception
}
L'exemple suivant lance une exception de division par zéro et l'attrape dans le bloc catch.
#include <iostream>
using namespace std;
double division(int a, int b) {
if(b == 0) {
throw "Condition division par zéro !";
}
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;
}
Puisque nous levons une exception de type const char*, lors de la capture de cette exception, nous devons utiliser const char* dans le bloc catch. Si nous compilons et exécutons le code ci-dessus, cela produirait le résultat suivant :
Condition division par zéro !
Exceptions standard C++
C++ fournit une liste d'exceptions standard définies dans <exception> que nous pouvons utiliser dans nos programmes. Celles-ci sont organisées dans une hiérarchie de classes parent-enfant montrée ci-dessous :
Voici une brève description de chaque exception mentionnée dans la hiérarchie ci-dessus :
| N° | Exception et description |
|---|---|
| 1 | std::exception Une exception et classe parente de toutes les exceptions standard C++. |
| 2 | std::bad_alloc Peut être lancée par new. |
| 3 | std::bad_cast Peut être lancée par dynamic_cast. |
| 4 | std::bad_exception Utile pour gérer les exceptions inattendues dans un programme C++. |
| 5 | std::bad_typeid Peut être lancée par typeid. |
| 6 | std::logic_error Une exception qui théoriquement peut être détectée en lisant le code. |
| 7 | std::domain_error Exception lancée quand un domaine mathématiquement invalide est utilisé. |
| 8 | std::invalid_argument Lancée suite à des arguments invalides. |
| 9 | std::length_error Lancée quand une std::string trop grande est créée. |
| 10 | std::out_of_range Peut être lancée par la méthode 'at', par exemple std::vector et std::bitset<>::operator[](). |
| 11 | std::runtime_error Une exception qui théoriquement ne peut pas être détectée en lisant le code. |
| 12 | std::overflow_error Lancée si un débordement mathématique se produit. |
| 13 | std::range_error Survient quand vous essayez de stocker une valeur hors plage. |
| 14 | std::underflow_error Lancée si un sous-débordement mathématique se produit. |
Définir de nouvelles exceptions
Vous pouvez définir vos propres exceptions en héritant et en surchargeant la fonctionnalité de la classe exception. Voici l'exemple qui montre comment vous pouvez utiliser la classe std::exception pour implémenter votre propre exception de manière standard :
#include <iostream>
#include <exception>
using namespace std;
struct MyException : public exception {
const char* what() const throw() {
return "Exception C++";
}
};
int main() {
try {
throw MyException();
} catch(MyException& e) {
std::cout << "MyException attrapée" << std::endl;
std::cout << e.what() << std::endl;
} catch(std::exception& e) {
// Autres erreurs
}
}
Cela produirait le résultat suivant :
MyException attrapée Exception C++
Ici, what() est une méthode publique fournie par la classe exception et elle a été surchargée par toutes les classes d'exceptions filles. Cela retourne la cause d'une exception.
Langue C
- Maîtriser les opérateurs C++ : Guide complet avec exemples pratiques
- Commentaires C++ : Bonnes pratiques pour un code lisible et maintenable
- Maîtriser les templates de classe en C++ : Guide pratique
- Gestion des fichiers en C : Maîtriser les E/S avec fopen, fprintf, fread et fseek
- Maîtriser la gestion d'exceptions Java : try, catch, finally, throw et throws expliqués
- Maîtriser la gestion d'exceptions en C++ : Exemples pratiques try, catch, throw
- Maîtriser la gestion d'exceptions Python : utiliser try, except, finally et raise efficacement
- Maîtriser la gestion d'erreurs en C : Bonnes pratiques et techniques
- Langage C++ : Vue d'ensemble et caractéristiques clés