Table of Contents

Partie IV – Redéfinition par masquage

TD2

Question n°1

Nous souhaitons redéfinir dans une classe MyAdvCounter qui dérive de la classe MyCounter une nouvelle méthode increment() en remplacement de la méthode actuelle dont le comportement est le suivant :

increment()
    si counter < max
        counter <- counter + 1
    sinon
        counter = max

Ie. le compteur ne revient pas à zéro et reste à max une fois la valeur max atteinte.

Correction

Correction

Il suffit de définir une classe similaire à la classe suivante :

class MyAdvCounter: public MyCounter
{
public:
    MyAdvCounter(): MyCounter() {}
    explicit MyAdvCounter(unsigned theMax):
        MyCounter(theMax)
    {}
    MyAdvCounter(unsigned theCounter,
        unsigned theMax): MyCounter(theCounter, theMax)
    {}
    MyAdvCounter(const MyBiDiCounter& anotherCounter):
        MyCounter(anotherCounter.counter)
    {}
 
    void increment()
    {
        if(counter < max)
            counter ++;
    }
    void print() const
    {
        std::cout << "Compteur: " << counter << "/" << max << std::endl;
    }
};

La méthode increment va masquer la classe MyCounter::increment dans la classe MyAdvCounter. Cependant, la méthode increment reste présente, elle n'est pas remplacée, elle est simplement 'cachée' ou 'masquée'. Il sera toujours possible de l'appeller en préfixant le nom de la fonction increment() par MyCounter::increment().

Question n°2

Tester le bon fonctionnement de la méthode à partir du code suivant et vérifier que le comportement est conforme

void testMyAdvCounter()
{
    MyAdvCounter incCounter(0, 4);
    for(int i=0; i < 6; i++)
    {
	  incCounter.increment();
        incCounter.print();
    }
}

Correction

Correction

Le compteur une fois la valeur 4 atteinte reste à la valeur 4.

Question n°3

Nous créons la fonction suivante :

void testCounter(MyCounter& unCompteur)
{
    for(int i=0; i < 6; i++)
    {
        unCompteur.increment();
        unCompteur.print();
    }
}

Tester la méthode en passant à la fonction testCounter un compteur de type MyCounter et un compteur de type MyAdvCounter. Expliquer le comportement de la fonction pour chacun des types de compteur.

Correction

Correction

En fait, c'est la méthode MyCounter::increment qui est appelé et non pas la méthode MyAdvCounter::increment. Pourquoi donc ?

En fait, nous avons transformé un objet de type MyAdvCounter en objet MyCounter. De ce fait, ce sont les méthodes visibles et accessibles par MyCounter qui sont appellées. En effet, les méthodes définies dans l'objet MyAdvCounter ne sont pas visibles et accessibles dans MyCounter, elles sont situés en dehors de la définition de l'objet. Donc même si l'objet auquel je fais référence est un objet qui contient des extensions à l'objet de type MyCounter, il n'est pas possible d'y accéder parce que mon horizon se limite uniquement aux définitions de MyCounter.

Ce comportement n'est pas sastisfaisant et nous souhaitons souvent de pouvoir remplacer la méthode définie dans la classe MyCounter::increment par une nouvelle méthode qui prendrait la place de la méthode MyCounter::increment. Nous verrons cela au moment où nous nous intéresserons au polymorphisme.