2. C++ Avancé




2.9. Les Exceptions

Le mécanisme d'exception permet une meilleure gestion des erreurs basé sur le déclenchement et l'interception d'instances de classes qui peuvent contenir des informations sur la cause de la levée de l'exception.

Les exceptions permettent la récupération sur erreur, c'est à dire le fait de pouvoir traiter une erreur sans que le programme ne termine en raison de l'erreur générée.

2.9.1. Intercepter une exception : le bloc try catch

try {
 ... code ...
} catch(exception& e) {
	cerr << e.what() << endl;
}

2.9.2. Lever une exception : throw

  1. #include <exception>
  2. #include <iostream>
  3. #include <string>
  4. #include <stdexcept>
  5. using namespace std;
  6.  
  7. // throws int *
  8. int divide_1(int a, int b) {
  9.     if (b == 0) throw new int(0);
  10.     return a / b;
  11. }
  12.  
  13. // throws string
  14. int divide_2(int a, int b) {
  15.     if (b == 0) throw string("division by 0");
  16.     return a / b;
  17. }
  18.  
  19. // throws std::exception
  20. int divide_3(int a, int b) {
  21.     if (b == 0) throw invalid_argument("division by zero");
  22.     return a / b;
  23. }
  24.  
  25. int main() {
  26.     int result;
  27.    
  28.     try {
  29.         result = divide_1(10, 2);
  30.         cerr << "10 / 2 = " << result << endl;
  31.         result = divide_1(10, 0);
  32.         cerr << "10 / 0 = " << result << endl;
  33.     } catch(int *e_int) {
  34.         cout << "exception: thrown for division by " << *e_int << endl;
  35.     }
  36.    
  37.     try {
  38.         result = divide_2(10, 2);
  39.         cerr << "10 / 2 = " << result << endl;
  40.         result = divide_2(10, 0);
  41.         cerr << "10 / 0 = " << result << endl;
  42.     } catch(string& s) {
  43.         cout << "exception: " << s << endl;
  44.     }
  45.    
  46.     try {
  47.         result = divide_3(10, 2);
  48.         cerr << "10 / 2 = " << result << endl;
  49.         result = divide_3(10, 0);
  50.         cerr << "10 / 0 = " << result << endl;
  51.     } catch(std::exception& e) {
  52.         cout << "exception: " << e.what() << endl;
  53.     }
  54.    
  55.    
  56.     return 0;
  57. }
  58.  
10 / 2 = 5
exception: thrown for division by 0
10 / 2 = 5
exception: division by 0
10 / 2 = 5
exception: division by zero

2.9.3. Liste d'exceptions levées par un sous-programme

Il est possible de déclarer les exceptions qui peuvent être levées par un sous-programme en les spécifiant dans la déclaration de la fonction :

void ma_fonction(parameters, ...) 
    throw (invalid_argument, runtime_error) {
    ...
} 

C++11 introduit le mot clé noexcept si on désire spécifier qu'un sous-programme ne lève pas d'exception.

Consulter ce lien pour en savoir plus sur les catégories d'exceptions.