User Tools

Site Tools


in204:tds:sujets:td6:part3

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
in204:tds:sujets:td6:part3 [2020/11/01 10:51]
bmonsuez
— (current)
Line 1: Line 1:
-====== Partie III –  Augmenter l’expressivité des exceptions====== 
- 
-[[in204:​tds:​sujets:​td6|TD6]] 
- 
-Nous souhaitons créer une nouvelle classe d’exception qui dérive de la classe exception et qui compte le nombre de fois qu’une exception est capturée. 
-Nous proposons que cette exception extended_exception dérive de la classe de base std::​exception et fournisse en complément des méthodes offertes par la classe de base les méthodes suivantes : 
- 
-<code cpp> 
-#​include<​exception>​ 
-... 
- 
-class extended_exception : public std::​runtime_error 
-{ 
-  public: 
-    void catched(); 
-      // Est appelé chaque fois que l’on souhaite indiqué à la classe qu’elle a été 
-      // capturée. ​ 
-   int getCatchNumber() const; 
-      // Retourne le nombre de fois que l’exception a été capturée. 
-}; 
-</​code>​ 
- 
-===== Question n°1 =====  
- 
-Proposer une implantation de cette classe. ​ 
- 
-<hidden Correction>​ 
- 
- 
-Nous proposons d'​ajouter un compteur qui est incrémenté à chaque fois que l'​exception a été capturée, ie. que la méthode ''​catched''​ a été appellée. Par défaut ce compteur est initialisé à zéro. 
-<code cpp> 
-#​include<​exception>​ 
-... 
-  
-class extended_exception:​ public std::​runtime_error 
-{ 
-private: 
-    private unsigned m_catched = 0;    ​ 
-public: 
-    void catched() { m_catched ++; } 
-      // Est appelé chaque fois que l’on souhaite indiqué à la classe qu’elle a été 
-      // capturée. ​ 
-   int getCatchNumber() const { return m_catched; } 
-      // Retourne le nombre de fois que l’exception a été capturée. 
-}; 
-</​code>​ 
- 
-Il est nécessaire de définir les constructeurs pour cette classe : 
-<code cpp> 
-class extended_exception:​ public std::​runtime_error 
-{ 
-... 
-public: 
-    explicit extended_exception(const std::​string&​ aMessage): ​ 
-        runtime_error(aMessage) 
-    {} 
-    explicit extended_exception(const char* aMessage): ​ 
-        runtime_error(aMessage) 
-    {} 
-... 
-</​code>​ 
- 
-</​hidden>​ 
- 
-===== Question n°2 =====  
- 
-Nous proposons de créer une classe exception ''​extended_divide_by_zero''​ qui se comporte comme la classe ''​divide_by_zero''​ mais qui dérive de la classe ''​extended_exception''​. 
- 
-Réaliser une implantation de la classe extended_divide_by_zero. 
- 
-<hidden Correction>​ 
- 
- 
-La nouvelle classe ''​extended_divide_by_zero''​ dérive directement de la classe ''​extended_exception''​. Ce qui nous donne le code suivant : 
- 
-<code cpp> 
-class extended_divide_by_zero:​ public extended_exception 
-{ 
-public: ​ 
-    division_by_zero():​ extended_exception("​Division by zero") 
-    {} 
-}; 
-</​code>​ 
- 
-</​hidden>​ 
- 
-===== Question n°3 =====  
- 
-Nous proposons de modifier la fonction ''​divide''​ pour qu’elle lance non plus une exception ''​divide_by_zero''​ mais ''​extended_divide_by_zero''​. 
- 
-Nous souhaitons tester cette nouvelle fonction avec le code suivant : 
- 
-<code cpp> 
-double successive_division(double i) nexcept(false) 
- 
-void test_succesive_division() noexcept 
-{ 
- double i; 
- std::cout << "The numerator: "; 
- std::cin >> i; 
- try { 
- successive_division(i);​ 
- } 
- catch (extended_division_by_zero e) { 
- e.catched();​ 
- std::cout << "​Division by zero occurred after " ​ 
- << e.getCatchNumber() 
- << " divisions"​ << std::endl; 
- } 
-} 
- 
-double successive_division(double i)  
- noexcept(false) 
-{ 
-  double j; 
-  std::cout << "Next divisor (-1 to stop sequence): "; 
-  std::cin >> j; 
-  if (j == -1) 
- return i; 
-  try { 
- successive_division(j);​ 
- return divide(i,​j);​ 
-  } 
-  catch(division_by_zero e) 
-  { 
-   throw extended_division_by_zero();​ 
-  } 
-  catch (extended_division_by_zero e)  
-  { 
- e.catched();​ 
- throw e; 
-  } 
-} 
-</​code>​ 
- 
-Commentez le résultat de l’exécution. 
- 
-<hidden Correction>​ 
- 
-Si nous effectuons un appel à la fonction avec la séquence de chiffres suivante : 
-''​20 4 4 1 3 0 3 6 -1'',​ nous allons avoir 5 captures de l'​exception de type ''​extended_divide_by_zero''​. Cependant, nous allons avoir comme message que l'​exception s'est produite après ''​5''​ divisions. Ce qui est conforme. 
- 
-Ceci est effectivement logique, puisque quand nous effectuons la capture : 
- 
-<code cpp> 
-  try { 
-    successive_division(j);​ 
-    return divide(i,​j);​ 
-  } 
-  catch(extended_divide_by_zero e) { 
-    e.catched() ;  
-    throw e;  
-  } 
-  ... 
-</​code>​ 
- 
-l'​argument de la clause ''​catch''​ est ''​extended_divide_by_zero'',​ ce qui signifie que nous **dupliquons** l'​argument. Nous créons une copie de l'​ancienne exception qui ensuite sera détruite. Ensuite, nous augmentons la valeur du champ ''​m_catched''​ qui a été recopié. En conséquence,​ nous comptons bien le nombre de fois que l'​exception a été capturée à partir du moment où elle a été générée. 
- 
-Cependant, nous pouvons éviter de recopier l'​exception en effectuant un passage non pas par recopie mais par référence : 
- 
-<code cpp> 
-  try { 
-    successive_division(j);​ 
-    return divide(i,​j);​ 
-  } 
-  catch(extended_divide_by_zero&​ e) { 
-    e.catched() ;  
-    throw e;  
-  } 
-  ... 
-</​code>​ 
- 
-Dans ce cas, l'​exception n'est pas recopiée et supprimée mais modifiée et ensuite propagée. 
- 
-</​hidden>​ 
  
in204/tds/sujets/td6/part3.1604227880.txt.gz · Last modified: 2020/11/01 10:51 by bmonsuez