Pour être éditée, la classe CException
ne dispose actuellement que de la fonction display()
, malcommode.
Il serait préférable de surcharger l’opérateur <<
, mais si la classe CException
doit ultérieurement être dérivée pour être spécialisée (et elle le sera !), le polymorphisme de l’édition ne fonctionnera pas pour cette nouvelle classe.
C’est pourquoi nous allons en faire une classe utilitaire éditable (c’est-à-dire la faire dériver de
la classe IEditable
).
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__ */
Les modifications à apporter à la classe CException
sont les suivantes :
- la dériver publiquement de la classe
IEditable
(penser à inclure le fichierIEditable.hpp
) - modifier la méthode publique
display()
pour qu’elle satisfasse aux nécessités deIEditable
.
Le programme ci-dessous est seulement destiné à vérifier que les différents
fichiers ci-dessus sont justes, et que le polymorphisme est correctement implémenté pour
les classes IEditable
et CException
.
Dans l’espace de noms anonyme du fichier testCException.cpp
, dériver la classe
CExcFille
de CException
, lui ajouter directement dans la déclaration :
- la fonction
display()
, qui complète l’édition de sa classe
mère par un message spécifique (n’importe quoi) ; - un constructeur permettant de construire l’objet de la classe mère (passage d’un libellé et d’une constante entière).
Dans la fonction testCException()
, lever une exception de la classe CExcFille
.
Dans la fonction main()
, rétablir le traitement classique des exceptions, en utilisant le nouveau comportement éditable de la classe CException
:
int main () { try { testCException(); } 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; } return KNoExc; } // main()
Lui ajouter la vérification que la commande n’a aucun argument, comme dans l’exercice
“Classe abstraite IEditable
”
Compiler et tester.
Vérifier que la fonction main()
affiche bien l’exception levée.
La classe CException
est elle aussi devenue un utilitaire.
Pour simplifier les éditions de liens ultérieures, nous vous recommandons de plus d’effectuer les
traitements suivants :
- compiler le fichier
CException.cpp
, par :g++ -c CException.cpp -I rep
où rep est le répertoire ou se trouve
CException.h
.Noter l’option
-I
du compilateurg++
qui permet de lui indiquer un chemin où trouver les fichiers de l’utilisateur à inclure s’ils ne sont pas dans le répertoire courant. - ajouter le fichier objet ainsi obtenu dans la bibliothèque
libUtil.a
:ar -cqs libUtil.a CException.o
Vérifier par :
ar -t libUtil.a
Lorsque vous aurez besoin d’utiliser les exceptions (toujours à partir de maintenant) il faudra modifier votre .pro
en lui ajoutant la ligne :
LIBS += -L rep -lUtil
où rep est le répertoire où se trouve le fichier libUtil.a
.