Table of Contents

Partie I – Manipulation des Exceptions

TD7

Question n°1 : Gestion simple des exceptions en C++

Question n°1.1

Implanter le code suivant dans un nouveau projet.

#include <iostream>
 
double divide(double a, double b);
void test_divide();
 
void test_divide()
{
  double i, j;
  for(;;) {
    std::cout << "Le numerateur (0 pour arreter): ";
    std::cin >> i;
    if(i == 0)
      break;
    std::cout << " Le denominateur : ";
    std::cin >> j;
    std::cout << "Resultat: " << divide(i,j) << std::endl;
  } 
}
 
double divide(double a, double b)
{
  try {
    if(!b) throw b; 
  }
  catch (double b) {
    std::cout << "Ne peut pas diviser par zero.\n";
    return b;
  }
  return a/b;
}
 
void main()
{
    test_divide() ;
}

Question n°1.2

Procéder à une exécution et regarder ce qui se passe quand une division par 0 se produit.

Correction

Correction

Lors d'une division par zéro se produit, le code

    std::cout << "Ne peut pas diviser par zero.\n";
    return b;

est exécuté et la fonction retourne 0. Ceci signifie que l'exception de type double ayant pour valeur 0 a été générée et a été capturée par la clause catch(double).

try {
    if(!b) throw b; 
  }
  catch (double b) {
    std::cout << "Ne peut pas diviser par zero.\n";
    return b;
  }

Dans les autres cas, c'est bien le résultat de la division qui est retournée par la fonction.

Question n°1.3

Exécuter en mode débogage et placer un point d’arrêt sur le code de capture de l’exception.

Correction

Correction

L'objectif de cette question est de vous faire manipuler vos outils pour utiliser l'environnement de dévogage de votre environnement de développement. Bien entendu, en fonction de votre environnement, vous avez des procédures différentes pour positionner un point d'arrêt.

Pour mémoire, voici quelques références pour placer des points d'arrêts sur les différents outils (sans garantie aucune d'exhaustivité).

Question n°2 : Création d’une classe d’exception

Nous envisageons désormais faire les choses correctement. Nous souhaitons définir une classe exception qui dérive de la classe std::exception se trouvant définie dans le fichier d'entête <exception>. Plus spécifiquement, nous souhaitons la faire dériver de la classe std::runtime_error qui elle-même dérive de std::exception.

Cette classe devra s’appeler division_by_zero.

Question n°2.1

Créer la classe division_by_zero. Elle pourra être définie dans un fichier d’entête math.hpp qui contiendra aussi l’entête de la fonction divide. Le fichier associé math.cpp contiendre la code de la fonction divide.

Penser à fournir un message d’erreur cohérent.

Correction

Correction

Nous nous proposons de créer un fichier math.hpp qui a le contenu suivant :

#ifndef mathHPP
#define mathHPP
 
#include<exception>
#include<stdexcept>
 
class division_by_zero: public std::runtime_error
{
public: 
    division_by_zero(): std::runtime_error("Division by zero")
    {}
};
 
double divide(double a, double b); 
#endif

Ainsi que le fichier math.cpp qui contient le code de la fonction divide.

#include "math.hpp"
 
double divide(double a, double b) 
{
  try {
    if(!b) throw b; 
  }
  catch (double b) {
    std::cout << "Ne peut pas diviser par zero.\n";
    return b;
  }
  return a/b;
}

Question n°2.2

Modifier les fonctions divide et test_divide pour prendre ne plus lancer et capturer une exception de type double mais de type division_by_zero.

Correction

Correction

La fonction modifiée s'écrit dorénavant comme suit :

inline double divide(double a, double b)
{
  try {
    if(b == 0) 
        throw division_by_zero(); 
  }
  catch (division_by_zero) {
    std::cout << "Ne peut pas diviser par zero.\n";
    return 0;
  }
  return a/b;
}