PROFDINFO.COM

Votre enseignant d'informatique en ligne

Révision des notions avancées de la programmation orientée objets - Réponses

1) Constructeurs et destructeurs

  1. Déterminer l’ordre d’appel des constructeurs et l’ordre d’appel des destructeurs.

    Constructeurs: CVehicule, CAutomobile, CDecapotable (de la classe de base vers la classe dérivée)
    Destructeurs: CDecapotable, CAutomobile, CVehicule (de la classe dérivée vers la classe de base)


  2. De qu’elle façon allez-vous procéder afin de déterminer ces séquences d’appel?

    Implémenter les classes CVehicule, CAutomobile, CDecapotable;
    Afficher un message à l'écran dans chaque constructeur et chaque destructeur;
    Coder un programme principal qui crée et détruit un objet CDecapotable.


  3. Qu’est-ce qui a motivé les concepteurs du C++ à opter pour un ordre précis? 

    Puisque la partie de l'objet de la classe
    dérivée peut utiliser les membres de la classe de base, ces derniers doivent exister avant pour éviter des références à des éléments inexistants. Pour la même raison, la partie de l'objet contenant les membres de la classe de base doit être détuite après l'enfant.

2) Pointeurs de base

  1. Quels sont les lignes pour lesquels le compilateur génère une erreur?
  2.  

    CDecapotable*  Obj1   = new CDecapotable;
    CDecapotable*  Obj2   = new CAutomobile;
    CDecapotable*  Obj3   = new CAvion; 
    CDecapotable*  Obj4   = new CVehicule; 
    CAutomobile*   Obj5   = new CDecapotable;
    CAutomobile*   Obj6   = new CAutomobile;
    CAutomobile*   Obj7   = new CAvion;
    CAutomobile*   Obj8   = new CVehicule; 
    CAvion*  	   Obj9   = new CDecapotable;
    CAvion* 	   Obj10  = new CAutomobile;
    CAvion* 	   Obj11  = new CAvion;
    CAvion* 	   Obj12  = new CVehicule; 
    CVehicule* 	   Obj13  = new CDecapotable;
    CVehicule* 	   Obj14  = new CAutomobile;
    CVehicule* 	   Obj15  = new CAvion;
    CVehicule* 	   Obj16  = new CVehicule; 

  3. Quelle conclusion tirez-vous de cette expérience?

    Un pointeur d'une classe peut pointer vers un objet de la même classe ou d'un classe dérivée.


3) Redéfinition de fonctions

Une classe peut implémenter une méthode et hériter de la même méthode de sa classe de base. 

  1. Pour chacun des programmes suivants, déterminez la version de la méthode Deplacer qui sera utilisée.

  2. CDecapotable*  Obj1 = new CDecapotable;
    CAutomobile*  Obj2 = new  CDecapotable;
    CAutomobile*  Obj3 = new  CAutomobile;
    CAvion*       Obj4 = new  CAvion;
    CVehicule*    Obj5 = new  CDecapotable;
    CVehicule*    Obj6 = new  CAutomobile;
    CVehicule*    Obj7 = new  CAvion;
    CVehicule*    Obj8 = new  CVehicule; 
    
    Obj1->Deplacer(1.0f);	// CDecapotable
    Obj2->Deplacer(1.0f);   // CAutomobile
    Obj3->Deplacer(1.0f);	// CAutomobile
    Obj4->Deplacer(1.0f);   // CAvion
    Obj5->Deplacer(1.0f);	// CVehicule
    Obj6->Deplacer(1.0f);	// CVehicule
    Obj7->Deplacer(1.0f);	// CVehicule
    Obj8->Deplacer(1.0f);	// CVehicule

  3. De qu’elle façon le programme détermine-t-il la version de la méthode à utiliser?

    Selon le type de pointeur.

4)  Fonctions polymorphes

Le mot-clé virtual a été ajouté devant toutes les méthodes Deplacer.

  1. Pour chacun des programmes de l’exercice précédent, déterminez la version de la méthode Deplacer qui sera utilisée.
  2. CDecapotable*  Obj1 = new CDecapotable;
    CAutomobile*  Obj2 = new  CDecapotable;
    CAutomobile*  Obj3 = new  CAutomobile;
    CAvion*       Obj4 = new  CAvion;
    CVehicule*    Obj5 = new  CDecapotable;
    CVehicule*    Obj6 = new  CAutomobile;
    CVehicule*    Obj7 = new  CAvion;
    CVehicule*    Obj8 = new  CVehicule; 
    
    Obj1->Deplacer(1.0f);	// CDecapotable
    Obj2->Deplacer(1.0f);   // CDecapotable
    Obj3->Deplacer(1.0f);	// CAutomobile
    Obj4->Deplacer(1.0f);   // CAvion
    Obj5->Deplacer(1.0f);	// CDecapotable
    Obj6->Deplacer(1.0f);	// CAutomobile
    Obj7->Deplacer(1.0f);	// CAvion
    Obj8->Deplacer(1.0f);	// CVehicule
  3. De qu’elle façon le programme détermine-t-il la méthode à utiliser lorsque les méthodes sont virtuelles ?

    Selon le type d'objet créé.

5) Bubu, Toto et Titi

  1. Quelle est la sortie du programme?

    ++ Toto debut
    ++ Toto y = 2
    ++ Bubu debut
    ++ Bubu x = 1
    ++ Bubu fin
    ++ Toto fin
    ++ Toto debut
    ++ Toto y = 7
    ++ Bubu debut
    ++ Bubu x = 3
    ++ Bubu fin
    ++ Toto fin
    ++ Titi debut
    ++ Titi z = 5
    ++ Titi fin
    -- Titi debut z = 5
    -- Titi fin
    -- Toto debut y = 7
    -- Bubu debut x = 3
    -- Bubu fin
    -- Toto fin
    -- Toto debut y = 2
    -- Bubu debut x = 1
    -- Bubu fin
    -- Toto fin


    (Les objets de base sont créés avant les objets dérivés, donc lorsque l'on crée un Titi, un Toto est d'abord créé. Le Bubu est créé au moment où le constructeur de Toto assigne un nouveau Bubu à pbu)

    (Les objets sont détruits dans l'ordre inverse où ils ont été créés, donc ti d'abord et to ensuite; lorsque ti est détruit, le Titi dérivé est détruit d'abord et le Toto ensuite; le Bubu est détruit lorsque le destructeur de Toto appelle delete pbu)


  2. On ajoute la fonction membre imprimer() dans la classe Toto et on modifie le main():

    Donnez la sortie des instructions A et B.

    Toto::imprimer: 6 7
    Toto::imprimer: 8 17


    (La fonction imprimer existe dans Toto et est héritée dans Titi. Lorsqu'elle imprime, elle affiche les attributs du Toto (et donc de son Bubu interne)

  1. On ajoute la fonction membre imprimer() dans la classe Titi :
  2. Donnez la sortie des instructions A et B de la question précédente.

    Toto::imprimer: 6 7
    Titi::imprimer: 8 17 0

    (Cette fois-ci, il existe une version de imprimer() dans Toto et une autre dans Titi, qui écrase la version héritée du Toto de base. Comme to est un Toto et que ti est un Titi, chacun utilise sa version.)

  3. On modifie le programme principal :

    Donnez la sortie des instructions A, B et C.

  4. Toto::imprimer: 44 55
    Titi::imprimer: 11 33 33
    Toto::imprimer: 11 33

    (Cette fois-ci, on a des pointeurs qui ne pointent pas nécessairement toujours sur un objet du même type. Comme il n'y a pas encore de polymorphisme, la version de imprimer() utilisée dépendra simplement du type du pointeur et non pas du type de l'objet pointé. Le fait de faire pointe pto vers un Titi ne change rien, pto->imprimer() utilise la version du Toto)

  5. On ajoute le mot-clé virtual devant la fonction membre imprimer de la classe Toto :
  6. Donnez la sortie des instructions A, B, C de la question précédente.

    Toto::imprimer: 44 55
    Titi::imprimer: 11 33 33
    Titi::imprimer: 11 33 33


    (Maintenant il y a polymorphisme à cause du virtual. La version utilisée sera donc la plus spécialisée possible lorsque le pointeur référence un objet d'une classe dérivée. Les deux premières instructions ne sont pas affectées mais le dernier pto->imprimer() utilise Titi::imprimer() puisque pto pointe vers un Titi à ce moment-là.)

6) Les ballons

a)

??
??
??
??
??
??
??
??
??
??

b)

??
:(
:)
:)
:)
??
??
??
??
??

c)

??
:(
:)
()
O
??
??
??
??
??

d)

??
:(
:)
()
O
??
??
??
??
??

e)

??
:(
:)
()
O
??
??
??
??
??

f)

??
:(
:)
()
O
??
:(
:)
()
O