La classe Duree
a été partiellement étudiée précédemment.
La dernière version qui en a été faite sert de point de départ à cet exercice.
Créer le projet CDureeEditable
.
Y incorporer les fichiers :
IEditable.hpp
/** * * \file IEditable.hpp * * \authors M. Laporte, D. Mathieu * * \date 10/02/2011 * * \version V1.0 * * \brief Codes d'erreurs * **/ #ifndef __IEDITABLE_HPP__ #define __IEDITABLE_HPP__ #include <iostream> namespace nsUtil { class IEditable; std::ostream & operator << (std::ostream & os, const IEditable & obj); class IEditable { virtual std::ostream & display (std::ostream & os) const = 0; public : virtual ~IEditable (void) {} friend std::ostream & operator << (std::ostream & os, const IEditable & obj); }; // IEditable } // namespace nsUtil inline std::ostream & nsUtil::operator << (std::ostream & os, const IEditable & obj) { return obj.display (os); } #endif /* __IEDITABLE_HPP__ */
Duree.h
/** * * \file Duree.h * * \authors M. Laporte * * \date 02/04/2018 * * \version V2.0 * * \brief déclarations de la classe Duree (avec constructeurs et * destructeur) * **/ #ifndef __DUREE_H__ #define __DUREE_H__ namespace nsUtil { typedef unsigned long long ULLong_t; class Duree { private : ULLong_t myDuree; short unsigned mySeconds; short unsigned myMinutes; short unsigned myHours; ULLong_t myDays; void normaliser (void); public : Duree (const ULLong_t duree = ULLong_t (0)); Duree (const Duree & duree); ~Duree (void); ULLong_t getDuree (void) const; void display (void) const; void incr (const ULLong_t delta = ULLong_t (0)); void decr (const ULLong_t delta = ULLong_t (0)); Duree operator + (const Duree & d) const; Duree operator - (const Duree & d) const; bool operator > (const Duree & d) const; bool operator < (const Duree & d) const; bool operator != (const Duree & d) const; bool operator == (const Duree & d) const; }; // Duree } // nsUtil #endif /* __DUREE_H__ */
Duree.cpp
/** * * \file Duree.cpp * * \authors M. Laporte * * \date 02/04/2018 * * \version V2.0 * * \brief définitions de la classe Duree * **/ #include <iostream> #include <iomanip> // setw() #include "Duree.h" using namespace nsUtil; using namespace std; #define DUREE nsUtil::Duree DUREE::Duree (const ULLong_t duree /* = ULLong_t (0) */) : myDuree (duree) { normaliser (); cout << "duree construite : "; display (); cout << endl; } // Duree() DUREE::Duree (const Duree & duree) : myDuree (duree.getDuree ()) { normaliser (); cout << "duree construite par recopie : "; display (); cout << endl; } // Duree() DUREE::~Duree (void) { cout << "duree détruite : "; display (); cout << endl; } // Duree() void DUREE::normaliser (void) { myDays = myDuree / 86400; myHours = (myDuree % 86400) / 3600; myMinutes = (myDuree % 3600) / 60; mySeconds = myDuree % 60; } // normaliser() ULLong_t DUREE::getDuree (void) const { return myDuree; } void DUREE::display (void) const { cout << '[' << setw (10) << myDays << " jour (s) " << setfill ('0') << setw (2) << myHours << " heure(s) " << setw (2) << myMinutes << " minute(s) " << setw (2) << mySeconds << " seconde(s) " << setfill (' ') << ']'; } // display() void DUREE::incr (const ULLong_t delta /* = ULLong_t (0) */) { myDuree += delta; normaliser (); } // incr() void DUREE::decr (const ULLong_t delta /* = ULLong_t (0) */) { myDuree -= (delta > myDuree) ? myDuree : delta; } // decr() DUREE DUREE::operator + (const Duree & d) const { return myDuree + d.myDuree; } // operator +() DUREE DUREE::operator - (const Duree & d) const { return myDuree - (myDuree < d.myDuree ? myDuree : d.myDuree); } // operator -() bool DUREE::operator > (const Duree & d) const { return myDuree > d.myDuree; } // operator >() bool DUREE::operator < (const Duree & d) const { return myDuree < d.myDuree; } // operator <() bool DUREE::operator != (const Duree & d) const { return myDuree != d.myDuree; } // operator !=() bool DUREE::operator == (const Duree & d) const { return myDuree == d.myDuree; } // operator ==() #undef DUREE
De nombreuses améliorations vont lui être apportées.
Copiez aussi le programme de test
testDuree.cpp
/** * * @file TestDuree.cpp * * @authors M. Laporte, D. Mathieu * * @date 17/03/2010 * * @version V1.0 * * @brief Test de la classe CDuree complete * **/ #include <cassert> #include <sstream> #include <exception> #include <iostream> #include "CException.h" // de l'exercice précédent #include "CstCodErr.h" #include "Duree.h" using namespace std; using namespace rel_ops; using namespace nsUtil; // CException namespace { void testDuree_01 (void) { DureeEditable d1 (3661); DureeEditable d2 (2661); DureeEditable d3 (3661); assert (! (d1 < d2)); assert ( (d2 < d1)); assert ( d1 > d2); assert (! (d2 > d1)); assert (! (d1 <= d2)); assert ( d2 <= d1); assert ( d1 >= d2); assert (! (d2 >= d1)); assert (! (d1 == d2)); assert (! (d2 == d1)); assert ( d1 == d3); assert ( d1 != d2); assert ( d2 != d1); } // testDuree_01() void testDuree_02 (void) { DureeEditable d1 (3661); { ostringstream oss; oss << d1; assert (oss.str() == "[ 0:01:01:01]"); } { ostringstream oss; oss << d1--; assert (oss.str() == "[ 0:01:01:01]"); } { ostringstream oss; oss << d1--; assert (oss.str() == "[ 0:01:01:00]"); } { ostringstream oss; oss << --d1; assert (oss.str() == "[ 0:01:00:58]"); } { ostringstream oss; oss << d1; assert (oss.str() == "[ 0:01:00:58]"); } { ostringstream oss; oss << d1++; assert (oss.str() == "[ 0:01:00:58]"); } { ostringstream oss; oss << d1++; assert (oss.str() == "[ 0:01:00:59]"); } { ostringstream oss; oss << ++d1; assert (oss.str() == "[ 0:01:01:01]"); } { ostringstream oss; oss << ++d1; assert (oss.str() == "[ 0:01:01:02]"); } { ostringstream oss; oss << ++d1; assert (oss.str() == "[ 0:01:01:03]"); } { ostringstream oss; oss << (d1 -= 3); assert (oss.str() == "[ 0:01:01:00]"); } { ostringstream oss; oss << (d1 += 3); assert (oss.str() == "[ 0:01:01:03]"); } { ostringstream oss; oss << (d1 += Duree (3)); assert (oss.str() == "[ 0:01:01:06]"); } { d1.setDuree (0); ostringstream oss; oss << d1; assert (oss.str() == "[ 0:00:00:00]"); } } // testDuree_02) void testDuree_03 (void) { DureeEditable d1; bool isCaught = false; try { d1--; } catch (const CException & e) { isCaught = true; } assert (isCaught); isCaught = false; try { --d1; } catch (const CException & e) { isCaught = true; } assert (isCaught); isCaught = false; try { d1 -= 1; } catch (const CException & e) { isCaught = true; } assert (isCaught); isCaught = false; try { d1 -= Duree (3); } catch (const CException & e) { isCaught = true; } assert (isCaught); } // testDuree_03() } // namespace anonyme int main (int argc, char * argv []) { if (argc != 1) { cerr << "Nombre d'arguments invalide\n" "Usage : TestCDuree\n"; return KErrArg; } try { testDuree_01 (); testDuree_02 (); testDuree_03 (); cout << "Fin normale\n"; return KNoExc; } catch (const CException & e) { cerr << e << '\n'; return e.getCodErr(); } catch (const exception & e) { cerr << "Exception standard : " << e.what() << '\n'; return KExcStd; } catch (...) { cerr << "Exception inconnue\n"; return KExcInconnue; } } // main()
Modifications à effectuer dans la classe Duree
:
- ajouter le qualifieur
explicit
devant le constructeur par défaut (cela évite les conversions implicites
de n’importe quel entier enDuree
, que pourrait faire indûment le compilateur), - remplacer les fonctions
incr()
etdecr()
par les opérateurs de pre/post-in/dé crémentation,CX & operator ++ (void) noexcept; // préincrémentation de la classe CX CX operator ++ (int) noexcept; // postincrémentation de la classe CX
- ajouter les deux surcharges de chacun des opérateurs d’affectation
+=
et-=
ayant pour paramètre soit un entierunsigned long long
, soit un objetDuree
(profile),Duree & operator += (const Duree &) noexcept;
- ajouter les deux opérateurs
+
et-
ayant pour paramètre un entier
unsigned long long
, - ajouter le modifieur
setDuree()
ayant pour paramètre ununsigned long long
avec une valeur
par défaut, - les opérateurs
-
,--
et-=
sont susceptibles de lever une
CException
de code d’erreurKExcOpInterdite
de valeur201
.
Un objet ne doit pas savoir comment il doit être affiché (nous avons fait une exception pour la classe
CException
qui a pour vocation d’être affiché sur un flux standard de sortie).
La fonction display()
n’a donc rien à faire dans la classe Duree
.
Dans l’espace de nom anonyme du fichier TestDuree.cpp
écrire la classe DureeEditable
.
-
- La dériver publiquement des classes
Duree
etIEditable
(penser à inclure les
fichiersIEditable.hpp
etDuree.h
). - Supprimer la fonction-membre publique
display()
de la classeDuree
et ajouter la fonction-membre protégéedisplay()
, de même profil que la fonction abstraitedisplay()
deIEditable
à la classeDureeEditable
.
- La dériver publiquement des classes
Modifier la fonction main()
du fichier TestDuree.cpp
, pour lui conserver la structure qui a été utilisée dans l’exercice précédent.
Compiler et tester.