===== Partie IV – Redéfinition par masquage ===== [[in204:tds:sujets:td2|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. 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(); } } 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. 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.