M2103-TP6-Exo-1

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.