User Tools

Site Tools


in204:tds:sujets:td2:part1

This is an old revision of the document!


Partie I – Création d’une classe dérivée

TD2

Dupliquez vos projets de compteurs en C++ que vous avez réalisé la semaine dernière. Pour ceux qui n’ont pas de projets compteurs fonctionnels, vous pouvez partir de la solution présente en ligne.

Question n° 1

A partir de la classe MyCounter que vous avez développé la semaine, une nouvelle MyBiDiCounter. Cette classe doit ajouter deux méthodes à la classe de base :

  • Une première méthode decrement qui décrémente le compteur, cette méthode correspond au pseudo-code suivant :
decrement()
    si counter > 0
    	counter <- counter – 1
    sinon
        counter = max;
  • Une seconde méthode print qui affiche l’état du compteur de la manière suivante.
print()
    affiche "Compteur : " counter "/" max (retour à la ligne)

Nous créons dans le fichier counter.hpp et ensuite de la classe MyCounter la classe MyBiDiCounter suivante:

class MyBiDiCounter: public MyCounter
{
public:
    void decrement() 
    {
        if(counter > 0) 
            counter --;
        else
            counter = max;
    }
 
    void print() const
    {
        std::cout << "Compteur: " << counter << "/" << max << std::endl;
    }
};

La classe MyBiDiCounter hérite de la classe MyCounter. Comme le qualificateur devant MyCounter est public,

  • l'ensemble des méthodes et champs publics de MyCounter sont visibles dans MyBiDiCounter et sont

aussi visibles par le code manipulant des objets de type MyBiDiCounter,

  • l'ensemble des méthodes et champs privés de MyCounter ne sont pas visibles dans MyBiDiCounter

La méthode print ne modifiant pas le contenu du compteur porte le qualificateur const.

Cependant le code précédent ne peut pas compiler, en effet, les méthodes decrement et print accèdent aux champs counter et max de la classe de base MyCounter. Mais ces champs sont déclarés dans la classe de base comme private, ils ne sont donc pas visibles en dehors de la classe MyCounter.

Ceci signifie que pour compiler, il est nécessaire de modifier la classe MyCounter comme suit:

class MyCounter
{
protected:   // En lieu et place de private
    uint counter;
    uint max;
public:
    ...
};

Question n°2

Tester votre nouveau compteur MyBiDiCounter en utilisant la fonction de test suivante.

void testMyBiDiCounter()
{
    MyBiDiCounter counterA;
    counterA.setMax(4);
    counterA.reset();
    counterA.print();
    for(int i=0; i < 6; i++)
    {
        counterA.increment();
        counterA.print();
    }
    for(int i=0; i < 6; i++)
    {
        counterA.decrement();
        counterA.print();
    }
}

Il s'agit de vérifier la bonne compilation et la bonne exécution.

Question n°3

On avait créé des constructeurs pour la classe MyCounter. Est-il possible de les appeler pour créer la classe MyBiDiCounter ?

En fait, il faut faire la distinction entre le constructeur par défaut. Dans ce cas, comme aucun constructeur n'est défini, C++ génère automatiquement le constructeur suivant :

class MyBiDiCounter: MyCounter
{    
    ...
public:
    MyBiDiCounter(): public MyCounter() {}
    ...
};

De même, il génère automatiquement le constructeur de recopie :

class MyBiDiCounter: public MyCounter
{ 
    ...
public:   
    MyBiDiCounter(const MyBiDiCounter& aCounter): MyCounter(aCounter) {}
    ...
};

Cependant, les constructeurs spécialisés ne peuvent pas être appellés. En effet, il y a peut-être des champs complémentaires dans la classe dérivée et dès lors, comment peut-on initialiser automatiquement ces champs complémentaires dans un constructeur spécialisé.

Il est donc nécessaire de redéfinir ces constructeurs spécialisés comme suit :

class MyBiDiCounter: public MyCounter
{ 
    ...
public:   
    explicit MyBiDiCounter(uint theMaxValue): MyCounter(theMaxValue) {}
    MyBiDiCounter(uint theCounterValue, uint theMaxValue): 
        MyCounter(theCounterValue, theMaxValue) {}
    ...
};
in204/tds/sujets/td2/part1.1600188408.txt.gz · Last modified: 2020/09/15 16:46 by bmonsuez