User Tools

Site Tools


in204:tds:sujets:td4:part2

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:td4:part2 [2019/10/15 11:00]
bmonsuez [Question 1.0]
in204:tds:sujets:td4:part2 [2022/11/18 10:49] (current)
Line 107: Line 107:
  
 <hidden Correction Complétion de la classe interval>​ <hidden Correction Complétion de la classe interval>​
 +
 Nous débutons par compléter la classe ''​interval''​. La classe ''​interval''​ doit exposer au moins deux méthodes que sont les méthodes :  Nous débutons par compléter la classe ''​interval''​. La classe ''​interval''​ doit exposer au moins deux méthodes que sont les méthodes : 
  
Line 207: Line 208:
  
  \\  \\
- 
  
 </​hidden>​ </​hidden>​
  
 <hidden Correction Complétion de la classe interval_iterator>​ <hidden Correction Complétion de la classe interval_iterator>​
 +<nodisp 2>
  
 Pour la classe ''​interval_iterator''​ nous devons implanter les exigences relatives à un [[https://​en.cppreference.com/​w/​cpp/​named_req/​ForwardIterator|forward iterator]]. ​ Pour la classe ''​interval_iterator''​ nous devons implanter les exigences relatives à un [[https://​en.cppreference.com/​w/​cpp/​named_req/​ForwardIterator|forward iterator]]. ​
Line 280: Line 281:
     }     }
 </​code>​ \\ \\ Il faut désormais implanter les opérateurs d'​incrémentation de l'​itérateur (ie. pour passer à la valeur suivante). C'est l'​opérateur ''​++''​ qui a est sélectionné,​ cependant cet opérateur possède deux syntaxes : (1) ''​++it''​ qui signifie applique l'​opération ''​++''​ à l'​objet ''​it''​ et retourne une référence à cet objet après que l'​opération ''​++''​ a été effectuée; (2) ''​it++''​ qui signifie fait une copie de l'​objet //copy//, applique l'​opération à l'​objet ''​it''​ et retourne l'​objet //copy// comme résultat de l'​opération. L'​opérateur ''​operator ++()''​ correspond à la première synataxe, l'​opérateur ''​operator ++(int)''​ correspond à la seconde syntaxe. Ce qui se traduit par : <​code>​ </​code>​ \\ \\ Il faut désormais implanter les opérateurs d'​incrémentation de l'​itérateur (ie. pour passer à la valeur suivante). C'est l'​opérateur ''​++''​ qui a est sélectionné,​ cependant cet opérateur possède deux syntaxes : (1) ''​++it''​ qui signifie applique l'​opération ''​++''​ à l'​objet ''​it''​ et retourne une référence à cet objet après que l'​opération ''​++''​ a été effectuée; (2) ''​it++''​ qui signifie fait une copie de l'​objet //copy//, applique l'​opération à l'​objet ''​it''​ et retourne l'​objet //copy// comme résultat de l'​opération. L'​opérateur ''​operator ++()''​ correspond à la première synataxe, l'​opérateur ''​operator ++(int)''​ correspond à la seconde syntaxe. Ce qui se traduit par : <​code>​
-    iterator&​ operator()+    iterator&​ operator++()
     {     {
         // Passe à la valeur suivant si nous ne sommes pas         // Passe à la valeur suivant si nous ne sommes pas
         // déjà à la fin de l'​interval.         // déjà à la fin de l'​interval.
-        if(mCurrent < mInterval->​maxValue)+        if(mCurrent <mInterval->​maxValue)
             mCurrent ++;             mCurrent ++;
         return *this;         return *this;
     }     }
-    iterator operator()+    iterator operator++(int)
     {     {
-        ​iterator ​it(*this); // Crée une copie de l'​itérateur.+        ​interval_iterator ​it(*this); // Crée une copie de l'​itérateur.
         ++(*this); ​         // Incrément l'​itérateur courant en appellant         ++(*this); ​         // Incrément l'​itérateur courant en appellant
                             // l'​opérateur iterator&​ operator()                             // l'​opérateur iterator&​ operator()
Line 296: Line 297:
     }     }
 </​code>​ \\ Il ne reste plus qu'à implanter les opérateurs relatifs à la comparaison. Deux itérateurs sont égaux s'ils font références à la même valeur située dans le même containeur. Dans ce cas, nous devons avoir les champs ''​mCurrent''​ et ''​mInterval''​ qui doivent être égaux. <code cpp> </​code>​ \\ Il ne reste plus qu'à implanter les opérateurs relatifs à la comparaison. Deux itérateurs sont égaux s'ils font références à la même valeur située dans le même containeur. Dans ce cas, nous devons avoir les champs ''​mCurrent''​ et ''​mInterval''​ qui doivent être égaux. <code cpp>
-    bool operator ==(const ​iterator& anotherIterator) const+    bool operator ==(const ​interval_iterator& anotherIterator) const
     {     {
         return mCurrent == anotherIterator.mCurrent && ​         return mCurrent == anotherIterator.mCurrent && ​
           *mInterval == *anotherIterator.mInterval;​           *mInterval == *anotherIterator.mInterval;​
     }     }
-    bool operator !=(const ​iterator& anotherIterator) const+    bool operator !=(const ​interval_iterator& anotherIterator) const
     {     {
         return mCurrent != anotherIterator.mCurrent ||          return mCurrent != anotherIterator.mCurrent || 
Line 307: Line 308:
     }     }
 </​code>​ </​code>​
 +  - Enfin, l'​itérateur doit aussi être [[https://​en.cppreference.com/​w/​cpp/​named_req/​CopyConstructible|constructible par recopie]], ​ [[https://​en.cppreference.com/​w/​cpp/​named_req/​CopyAssignable|supporter l'​affection]] et [[https://​en.cppreference.com/​w/​cpp/​named_req/​Swappable|supporter les permutations]]),​ ce qui impose de définir en complément le constructeur de recopie, les fonctions membres ''​swap''​ et l'​opérateur ''​=''​ comme suit: \\ <code cpp>
 +public:
 +    // Définition du constructeur de recopie.
 +    // Crée un itérateur qui fait référence au même élément que l'​itérateur
 +    // passé en argument.
 +    interval_iterator(const interval_iterator&​ anotherIterator):​
 +        mCurrent(anotherIterator.mCurrent),​ mInterval(anotherIterator.mInterval)
 +    {}
 +    // Définition de l'​opération d'​affectation consistant à ce que 
 +    // l'​itérateur courant fait référence au même élément que l'​itérateur
 +    // passé en argument.
 +    interval_iterator&​ operator=(const interval_iterator&​ anotherIterator)
 +    {
 +        mCurrent = anotherIterator.mCurrent;​
 +        mInterval = anotherIterator.mInterval;​
 +        return *this;
 +    } 
 +    // Opération de permutation. ​
 +    // A la fin de l'​opération, ​
 +    // - anotherIterator fait référence à l'​élément ​
 +    // qui était référencé par l'​itérateur courant avant l'​opération,​
 +    // - l'​itérateur courant ​ fait référence à l'​élément ​
 +    // qui était référencé par l'​itérateur anotherIterator avant l'​opération,​
 +    void swap(interval_iterator&​ anotherIterator)
 +    {
 +        std::​swap(mCurrent,​ anotherIterator.mCurrent);​
 +        std::​swap(mInterval,​ anotherIterator.mInterval);​
 +    }
 +</​code>​ \\ Et normalement l'​ensemble des éléments ont été définis pour à la classe ''​interval_iterator''​ pour que ce dernier puisse répondre aux exigences auxquelles un itérateur de type [[https://​en.cppreference.com/​w/​cpp/​named_req/​ForwardIterator|forward iterator]] doit répondre. ​    
  
 </​hidden>​ </​hidden>​
Line 315: Line 345:
  
 Tester le bon fonctionnement de classe avec le code suivant : Tester le bon fonctionnement de classe avec le code suivant :
 +
 +<code cpp>
 +
 +#​include"​interval.hpp"​
 +#​include<​algorithm>​
 +#​include<​iostream>​
 +#​include<​vector>​
 +
 +template<​class inputIterator>​
 +void print(inputIterator beginIt, inputIterator endIt)
 +{
 +    if(beginIt == endIt)
 +    {
 +        std::cout << "​[]"​ << std::endl;
 +        return;
 +    }    ​
 +    for(;;)
 +    {
 +        std::cout << *beginIt;
 +        beginIt++;
 +        if(beginIt == endIt)
 +            break;
 +        std::cout << ", ";
 +    }
 +    std::cout << "​]"​ << std::endl;
 +    return;
 +}
 +
 +void testInterval()
 +{
 +    interval inter(5, 15);
 +    std::cout << "​Contenu de l'​interval : "; ​
 +    print(inter.begin(),​ inter.end());​
 +    // Recherche du plus grand élément.
 +    auto maxIt = max_element(inter.begin(),​ inter.end());​
 +    std::cout << "​Element maximal de la séquence: " << *maxIt << std::endl;
 +    // Duplication des valeurs dans un vecteur
 +    std::​vector<​int>​ vec(inter.begin(),​ inter.end());​
 +    std::cout << "​Contenu du vecteur : "; ​
 +    print(vec.begin(),​ vec.end());
 +}
 +
 +int main()
 +{
 +    testInterval();​
 +    return 0;
 +}
 +</​code>​
 +
 +<hidden Explications>​
 +<nodisp 2>
 +
 +
 +  * La fonction ''​print''​ prend une séquence d'​éléments définie par un itérateur de début ''​beginIt''​ et un itérateur marquant la fin de la séquence ''​endIt''​ et affiche cette séquence sur la console. La seule particularité,​ c'est qu'en fonction de la position de l'​élément,​ le séparateur ","​ est placé entre les valeurs ou non.
 +
 +  * Dans le cas de la fonction ''​testInterval()'',​ le code <code cpp>
 +    interval inter(5, 15);
 +    </​code>​ crée un interval allant de 5 à 15. Nous appelons la fonction ''​print''​ en passant l'​itérateur référençant la première valeur contenue dans l'​interval ainsi que l'​itérateur marquant la fin de la séquence et nous vérifions que la fonction ''​print''​ peut bien afficher les valeurs contenues dans l'​interval. <code cpp>
 +    print(inter.begin(),​ inter.end());​
 +</​code>​. Nous vérifions en utilisant une fonction [[https://​en.cppreference.com/​w/​cpp/​algorithm/​max_element|max_element]] de la bibliothèque standard qui recherche le plus grand élément d'une séquence que notre containeur fonctionne aussi avec des fonctions de la bibliothèque standard. <code cpp>
 +    auto maxIt = max_element(inter.begin(),​ inter.end());​
 +    std::cout << "​Element maximal de la séquence: " << *maxIt << std::endl;
 +</​code>​Nous affichons l'​élément retourné qui est bien entendu la borne supérieure de l'​interval. Enfin, nous créons un vecteur auquel nous affectons l'​ensemble des valeurs contenues dans l'​interval ''​inter''​. Et nous vérifions que notre fonction ''​print''​ fonctionne aussi avec un containeur de type ''​std::​vector''​.<​code cpp>
 +    // Duplication des valeurs dans un vecteur
 +    std::​vector<​int>​ vec(inter.begin(),​ inter.end());​
 +    std::cout << "​Contenu du vecteur : "; ​
 +    print(vec.begin(),​ vec.end());
 +</​code>​
 +
 +</​nodisp>​
 +</​hidden>​
 +
  
in204/tds/sujets/td4/part2.1571137205.txt.gz · Last modified: 2019/10/15 11:00 by bmonsuez