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
explicitdevant 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 longavec une valeur
par défaut, - les opérateurs
-,--et-=sont susceptibles de lever une
CExceptionde code d’erreurKExcOpInterditede 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
DureeetIEditable(penser à inclure les
fichiersIEditable.hppetDuree.h). - Supprimer la fonction-membre publique
display()de la classeDureeet 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.