Avant de commencer, il est conseillé de réviser l’amphi consacré aux classes abstraites.
Nous avons montré, en cours, l’utilité d’écrire la classe abstraite IEditable
, afin de
permettre à toute classe qui en est dérivée de disposer de l’opérateur d’injection <<
qui mette en œuvre le polymorphisme.
Cela oblige tout utilisateur à écrire, pour chacune de ses propres classes, une fonction display()
privée ou protégée.
Travail demandé
Créer le projet ClasseEditable
.
Y copier le contenu des fichiers CException.h
,
/** * * \file CException.h * * \authors M. Laporte, D. Mathieu * * \date 10/02/2011 * * \version V1.0 * * \brief Declaration de la classe CException * **/ #ifndef __CEXCEPTION_H__ #define __CEXCEPTION_H__ #include <string> #include <exception> #include "CstCodErr.h" namespace nsUtil { class CException : public std::exception { std::string myLibelle; unsigned myCodErr; public : CException (const std::string & libelle = std::string(), const unsigned codErr = KNoExc) noexcept; virtual ~CException (void) noexcept; const std::string & getLibelle (void) const noexcept; unsigned getCodErr (void) const noexcept; virtual const char* what (void) const noexcept; void display (void) const; }; // CException } // namespace nsUtil #endif /* __CEXCEPTION_H__ */
CException.cpp
/** * * \file CException.cpp * * \authors M. Laporte, D. Mathieu * * \date 10/02/2011 * * \version V1.0 * * \brief classe CException * **/ #include <string> #include <iostream> #include "CstCodErr.h" #include "CException.h" using namespace std; #define CEXC nsUtil::CException //========================== // Classe nsUtil::CException //========================== CEXC::CException (const string & libelle /* = string () */, const unsigned codErr /* = KNoExc */) noexcept : myLibelle (libelle), myCodErr (codErr) {} const string & CEXC::getLibelle (void) const noexcept { return myLibelle; } // GetLibelle() unsigned CEXC::getCodErr (void) const noexcept { return myCodErr; } CEXC::~CException (void) noexcept {} const char* CEXC::what (void) const noexcept { return myLibelle.c_str(); } void CEXC::display (void) const { cout << "Exception : " << myLibelle << '\n' << "Code : " << myCodErr << endl; } // Afficher() #undef CEXC
et CstCodErr.h
/** * * \file CstCodErr.h * * \authors M. Laporte, D. Mathieu * * \date 10/02/2011 * * \version V1.0 * * \brief Codes d'erreurs * **/ #ifndef __CSTCODERR_H__ #define __CSTCODERR_H__ namespace nsUtil { enum {KNoExc = 0, KNoError = 0, KExcStd = 254, KExcInconnue = 255 }; } // namespace nsUtil #endif /* __CSTCODERR_H__ */
Dans le fichier IEditable.hpp
, écrire la classe abstraite IEditable
de l’espace de noms nsUtil
, conformément aux indications de l’amphi 4 de POO. Nous n’y avions pas défini l’opérateur ami <<
, voici sa définition :
ostream & operator << (ostream & os, const IEditable & editable) { editable.display (os); return os; } // operator <<()
Afin de tester le fonctionnement de cette classe, recopier dans l’espace de noms anonyme du fichier
ClasseEditable.cpp
, la fonction suivante :
void contenu (const IEditable & ed) { cout << ed << endl; }
Ajouter deux classes CA
et CB
, dérivées de IEditable
, qui ne se distinguent que par leur fonction virtuelle display()
(elles affichent leur identificateur).
Dans la fonction testClasseEditable()
de l’espace de noms anonyme du fichier
ClasseEditable.cpp
, instancier les classes CA
et CB
, et éditer les deux objets au moyen de la fonction contenu()
.
Garder à la fonction main()
la structure qui lui a été donnée dans le TP précédent :
fichier ClasseEditable.cpp :
/** * * \file : ClasseEditable.cpp * * \author : * * \date : * **/ #include <iostream> #include <exception> #include "CstCodErr.h" #include "CException.h" using namespace std; using namespace nsUtil; namespace { void testXXX (void) ... } // namespace int main (int argc, char * argv []) { try { testXXX (); return KNoExc; } catch (const CException & e) { cerr << "Erreur : " << e.getLibelle () << '\n' << "Code d'erreur = " << e.getCodErr () << '\n'; return e.getCodErr(); } catch (const exception & e) { cerr << "Exception standard : " << e.what () << '\n'; return KExcStd; } catch (...) { cerr << "Exception inconnue\n"; return KExcInconnue; } } // main()
Vérifier qu’aucun argument n’est passé à la commande.
Compiler et tester.
La classe IEditable
est devenue un utilitaire.