User Tools

Site Tools


in204:tds:sujets:td6:part1

Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
in204:tds:sujets:td6:part1 [2019/11/03 10:56]
bmonsuez [Question n°2.2]
in204:tds:sujets:td6:part1 [2022/11/18 10:49] (current)
Line 1: Line 1:
-====== Partie I – Manipulation ​des Exceptions======+====== Partie I – Définitions ​des exigences ​======
  
 [[in204:​tds:​sujets:​td6|TD6]] [[in204:​tds:​sujets:​td6|TD6]]
  
-===== Question n°1 : Gestion simple des exceptions en C++ ===== 
  
-==== Question n°1.1 ==== +===== Question n°1=====
  
-Implanter le code suivant dans un nouveau ​projet. ​+Créer ​un projet ​dans lequel vous intégrez le fichier "​simple_sort.hpp" qui contient la fonction de comparaison suivante:
  
 <code cpp> <code cpp>
 +#pragma once
 +#​include<​algorithm>​
  
-#​include ​<iostream+template<typename ​ iterator
- +void simple_sort(iterator startiterator end)
-double divide(double adouble b); +
-void test_divide();​ +
- +
-void test_divide()+
 { {
-  double i, j; +    ​for(;start != endstart ++
-  ​for(;;​) ​{ +    ​{ 
-    ​std::cout << "Le numerateur (0 pour arreter): "; +        auto it = start; it++
-    ​std::​cin >> i+        for(;it !end; it ++
-    if(== 0+        { 
-      ​break;​ +            // Compare si les deux elements sont dans le bon ordre. 
-    ​std::​cout << " Le denominateur : "; +            if (*start ​*it) 
-    ​std::​cin ​>> j; +                std::swap(*start*it); 
-    std::cout << "​Resultat:​ " << divide(i,j<< std::endl+        } 
-  +    ​}
 } }
 +</​code>​
  
-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() ; 
-} 
- 
-</​code>​ 
  
-==== Question n°1.==== +==== Question n°1.1 =====
  
-Procéder à une exécution et regarder ce qui se passe quand une division par 0 se produit.+Déterminer quel type d'​itérateur est requis pour effectuer les opérations ?
  
 <hidden Correction>​ <hidden Correction>​
-Lors d'une division par zéro se produit, le code  +Il s'​agit ​d'un itérateur
-<code cpp> +  
-    std::cout << "Ne peut pas diviser par zero.\n";​ +  * devant offrir une itération croissante, 
-    ​return b; +  * devant offrir ​la possibilité de reprendre ​l'itération à partir d'une position antérieurement stockée.
-</​code>​ +
-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)'​'.+
  
-<​code>​ +Si nous regardons les caractéristiques des itérateurs:​ [[https://​en.cppreference.com/​w/​cpp/​iterator|Iterator library]], nous constatons que: 
-try { +  
-    if(!b) throw b;  +  ​* //​LegacyInputIterator//:​ ne supporte pas plusieurs passes et ne supporte pas l'​écriture,​ 
-  ​} +  ​* //​LegacyForwardIterator//​supporte plusieurs passes mais ne supporte ​pas obligatoire l'​écriture,​ 
-  ​catch (double b) { +  ​//​LegacyOuputIterator//:​ supporte l'​écriture.
-    std::cout << "Ne peut pas diviser par zero.\n";​ +
-    return b; +
-  ​+
-</code>+
  
-Dans les autres casc'est bien le résultat de la division qui est retournée par la fonction.+De faitnous devons garantir à la fois la lecture et l'​écriture,​ ce qui signifie que nous devons nous assurer que l'​itérateur respect les contracts requis pour un //​LegacyForwardIterator//​ et un //​LegacyOuputIterator//​.
  
 </​hidden>​ </​hidden>​
-==== 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. 
  
-<hidden Correction>​ +==== Question n°1.2 =====
-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é).+Ajouter une contrainte imposant que le type passé à la fonction correspond bien au type d'itérateur que vous avez identifié.
  
-  * [[https://code.visualstudio.com/docs/cpp/​cpp-debug|Debug C++ in Visual Studio Code]]+<hidden Correction>​ 
 +<code cpp> 
 +template<​typename ​ iterator>​ 
 +void simple_sort(iterator start, iterator end)  
 +    requires(std::​forward_iterator<​iterator>​ && std::​input_or_output_iterator<​iterator>​) 
 +
 +    std::cout << "​Insertion Sort\n";​ 
 +    for(;start != end; start ++) 
 +    { 
 +        auto it = start; it++; 
 +        for(;it != end; it ++) 
 +        { 
 +            ​// Compare si les deux elements sont dans le bon ordre. 
 +            if (*start > *it) 
 +                std::​swap(*start,​ *it); 
 +        } 
 +    } 
 +
 +</code> 
 +</hidden>
  
-  * [[http://​wiki.codeblocks.org/​index.php/​Debugging_with_Code::​Blocks|Debugging with Code::​Blocks]] 
  
-  * [[https://​docs.microsoft.com/​fr-fr/​visualstudio/​debugger/​quickstart-debug-with-cplusplus?​view=vs-2019|Quickstart:​ Debug with C++ using the Visual Studio debugger]]+==== Question n°1.3 ====
  
-  * [[https://​medium.com/​yay-its-erica/​xcode-debugging-with-breakpoints-for-beginners-5b0d0a39d711|Xcode Debugging with Breakpoints (for Beginners)]]+Nous souhaitons ajouter l'​opérateur suivant qui liste l'​ensemble des éléments d'un conteneur:
  
-  * [[https://www.cs.swarthmore.edu/​~newhall/​unixhelp/​howto_gdb.php|gdb ​(and dddGuide]]+<code cpp> 
 +template<​typename ​ containerT, typename charT, typename traits = std::​char_traits<​charT>>​ 
 +std::​basic_ostream<​charT,​ traits>&​ operator << (std::​basic_ostream<​charT,​ traits>&​ aStream, const containerT&​ aContainer) 
 +
 +    aStream << "​{";​ 
 +    auto end = aContainer.end(); 
 +    for(auto it = aContainer.begin(); it != end;) 
 +    { 
 +        aStream << *it ++; 
 +        if(it != end) 
 +            aStream << ", "; 
 +    } 
 +    aStream << "​}";​ 
 +}  
 +</​code>​
  
-  * [[https://​www.emacswiki.org/​emacs/​DebuggingWithEmacs|Debugging with Emacs]]+Ajouter ce code à votre fichier '​simple_sort.hpp'​ et puis tester ensuite à la fois la précédente fonction et cette nouvelle fonction avec le code suivant ​:
  
-</hidden> +<code cpp>
-===== 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 [[https://​en.cppreference.com/​w/​cpp/​error/​exception|std::​exception]] se trouvant définie dans le fichier d'​entête [[https://​en.cppreference.com/​w/​cpp/​header/​exception|<exception>]]. Plus spécifiquement,​ nous souhaitons la faire dériver de la classe ​ [[https://​en.cppreference.com/​w/​cpp/​error/​runtime_error|std::​runtime_error]] qui elle-même dérive de [[https://​en.cppreference.com/​w/​cpp/​error/​exception|std::​exception]]+#include<list> 
 +#​include"​simple_sort.hpp"
  
-Cette classe devra s’appeler ''​division_by_zero''​.+int main()  
 +
 +    std::​list<​int>​ v = {1, 7, 3, 4, 9, 2, 5}; 
 +    simple_sort(v.begin(), v.end()); 
 +    std::cout << v; 
 +    return 0; 
 +
 +</​code>​
  
-==== 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.+==== Question n°1.4 ====
  
-Penser à fournir un message d’erreur cohérent. +Dans la question précédente, ​nous avons défini une nouvelle surcharge ​de l'opérateur %%<<​%%En fait, cette surcharge n'est pas optimale, puisqu'il suffit que je définisse un type quelconque non supporté et cela ne fonctionne plus :
- +
-<hidden Correction>​ +
- +
-Nous nous proposons ​de créer un fichier ​''math.hpp'' ​qui a le contenu suivant ​:+
  
 <code cpp> <code cpp>
-#ifndef mathHPP +#include<​list>​ 
-#define mathHPP +#include"​sort.hpp"​
- +
-#include<​exception>​+
  
-class division_by_zero:​ public std::​runtime_error+struct Toto {}; 
 +int main() ​
 { {
-public:  +    ​std::list<​int>​ v = {1, 7, 3, 4, 9, 2, 5}; 
-    division_by_zero(): ​std::runtime_error("​Division by zero"​) +    ​simple_sort(v.begin()v.end()); 
-    ​{+    std::cout << ​v
-}; +    ​std::cout << Toto() << std::endl
-#endif +    return ​0;
- +
-double divide(double adouble b) +
-+
-  try { +
-    if(!bthrow b +
-  } +
-  catch (double b) { +
-    std::cout << ​"Ne peut pas diviser par zero.\n"​+
-    ​return b+
-  } +
-  ​return ​a/b;+
 } }
- 
 </​code>​ </​code>​
  
-</​hidden>​ +Expliquer pourquoi le compilateur génére ​une erreur ?
-==== 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''​.+
  
 <hidden Correction>​ <hidden Correction>​
- +En fait, il n'y a pas de surcharge de l'​opérateur %%<<​%% pour le type `Toto`, en conséquence,​ le compilateur va rechercher dans les opérateurs qui n'ont pas de contraintes sur les types, vous vous souvenez qu'on essaye d'​abord les opérateurs les plus généraux et ensuite les moins généraux. Il trouve donc dans l'​espace de nom courant l'​opérateur ​ 
-La fonction modifiée s'écrit dorénavant comme suit :+
  
 <code cpp> <code cpp>
-inline double divide(double adouble b) +template<​typename ​ containerT, typename charTtypename traits ​std::​char_traits<​charT>>​ 
-+std::​basic_ostream<​charT,​ traits>&​ operator << ​(std::basic_ostream<charT, traits>&​ aStream, const containerT&​ aContainer) {...}
-  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; +
-}+
 </​code>​ </​code>​
 +
 +et ne sait pas que cet opérateur n'est définit que pour les objets qui sont des conteneurs au sens de la STL. En conséquence de quoi, il génère une erreur puisqu'​il essaye d'​instancier un code qui ne supporte pas des objets de type `Toto`.
  
 </​hidden>​ </​hidden>​
 +
 +
 +[[in204:​tds:​sujets:​td6:​part2|Partie 2]]
 +
  
in204/tds/sujets/td6/part1.1572778568.txt.gz · Last modified: 2019/11/03 10:56 by bmonsuez