PROFDINFO.COM

Votre enseignant d'informatique en ligne

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

1) Constructeurs et destructeurs

Voici la représentation UML de quatre classes CVehicule,  CAvion , CAutomobile et CDecapotable:
 

uml

 

La classe CDecapotable dérive de la classe CAutomobile qui elle-même dérive de la classe CVehicule.  Lors de la création d’un objet de la classe CDecapotable, Il y a donc trois constructeurs impliqués dans la création de l’objet.   De façon analogue, lorsqu’un objet CDecapotable est détruit, il y a trois destructeurs impliqués. 

  1. Déterminer l’ordre d’appel des constructeurs et l’ordre d’appel des destructeurs.
  2. De qu’elle façon allez-vous procéder afin de déterminer ces séquences d’appel?
  3. Qu’est-ce qui a motivé les concepteurs du C++ à opter pour un ordre précis? 

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?

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);
    Obj2->Deplacer(1.0f);
    Obj3->Deplacer(1.0f);
    Obj4->Deplacer(1.0f);
    Obj5->Deplacer(1.0f);
    Obj6->Deplacer(1.0f);
    Obj7->Deplacer(1.0f);
    Obj8->Deplacer(1.0f);

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

 

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. De qu’elle façon le programme détermine-t-il la méthode à utiliser lorsque les méthodes sont virtuelles ?

 

5) Bubu, Toto et Titi

Soit les déclarations et définitions suivantes:

#include <iostream>
using namespace  std;

class Bubu
    {
    public:
    int x;
    Bubu(int a);
    ~Bubu();
    };
class Toto
    {
    public:
    Bubu *  pbu;
    int y;
    Toto(int  a, int b);
    ~Toto();
    };
class Titi: public  Toto
    { 
    public:
    int z;
    Titi(int a, int b, int c);
    ~Titi();
    };
Bubu::Bubu(int a)
    {
    cout << "++ Bubu debut"  << endl;
    x = a;
    cout << "++  Bubu x = " << x << endl;
    cout  << "++ Bubu fin" << endl;
    }
Bubu::~Bubu() 
    {
    cout << "-- Bubu debut x = "  << x << endl;
    cout << "--  Bubu fin" << endl;
    }
Toto::Toto(int a, int b)
    {
    cout  << "++ Toto debut" << endl;
    y = b;
    cout  << "++ Toto y = " << y << endl;
    pbu = new  Bubu(a);
    cout << "++ Toto fin"  << endl;
    }
Toto::~Toto()
    {
    cout  << "-- Toto debut y = " << y << endl;
    delete pbu;
    cout  << "-- Toto fin" << endl;
    }
Titi::Titi(int a, int b, int c) :  Toto(a, a+b)
    {
    cout  << "++ Titi debut" << endl;
    z = c;
    cout  << "++ Titi z = " << z << endl;
    cout  << "++ Titi fin" << endl;
    }
Titi::~Titi()
    {
    cout  << "-- Titi debut z = " << z << endl;
    cout  << "-- Titi fin" << endl;
    }
int main()
    {
    Toto to(1,  2);
    Titi ti(3,  4, 5);

    }
  1. Quelle est la sortie du programme?
  2. On ajoute la fonction membre imprimer() dans la classe Toto et on modifie le main():

  3. class Toto
        {
        public:
            ... 
            void imprimer();
            ...
        };
    
    void  Toto::imprimer()
        {
        cout  << "Toto::imprimer: " << pbu->x << " "  << y << endl;
        }
    int main()
        {
        Toto to(6, 7);
        Titi ti(8, 9, 0);
        to.imprimer();              // Instruction A
        ti.imprimer();              // Instruction B
        }

    Donnez la sortie des instructions A et B.

  1. On ajoute la fonction membre imprimer() dans la classe Titi :

  2. class Titi: public  Toto
        { 
        public:  
            ... 
            void imprimer(); 
            ... 
        };
    
    void  Titi::imprimer()
        {
        cout  << "Titi::imprimer: " << pbu->x << " "  << y << " " << z << endl;
        }

    Donnez la sortie des instructions A et B de la question précédente.

  3. On modifie le programme principal :
  4.  

    int main()
        {
        Toto to(44, 55);
        Titi ti(11, 22, 33);
        Toto * pto;
        Titi * pti;
        pto = &to;
        pti = &ti;
        pto->imprimer(); // Instruction A
        pti->imprimer(); // Instruction B
        pto = pti;
        pto->imprimer(); // Instruction C
        }

    Donnez la sortie des instructions A, B et C.

  5. On ajoute le mot-clé virtual devant la fonction membre imprimer de la classe Toto :

  6. class Toto 
        { 
        public:  
            ... 
            virtual void imprimer(); 
            ...
        };

    Donnez la sortie des instructions A, B, C de la question précédente.

6) Les ballons

Voici un programme principal :

#include <iostream>
using namespace std; 

// Les classes sont déclarées ici!
int main()
    {
    Objet o;
    Porcelaine p;
    Ballon b;
    BallonRugby bR;
    BallonFoot bF;
    
    o.rebondir();
    p.rebondir();
    b.rebondir();
    bR.rebondir();
    bF.rebondir();
    
    Objet * po = &o;
    po->rebondir();
    po = &p; 
    po->rebondir();
    po = &b; 
    po->rebondir();
    po = &bR; 
    po->rebondir();
    po = &bF; 
    po->rebondir();
 }
       

Donnez la sortie de ce programme pour chacune des six (6) déclarations de classes suivantes:

a)

class Objet                      { public:		    void rebondir() { cout <<  "??" << endl; } };
class Porcelaine:  public Objet  { public:                                                   }; 
class Ballon:      public Objet  { public:                                                    }; 
class BallonRugby: public Ballon { public:                                                    }; 
class BallonFoot:  public Ballon { public:                                                    }; 

b)

class Objet                      { public:         void rebondir() { cout <<  "??" << endl; } };
class Porcelaine:  public Objet  { public:         void rebondir() { cout <<  ":(" << endl; } };
class Ballon:      public Objet  { public:         void rebondir() { cout <<  ":)" << endl; } };
class BallonRugby: public Ballon { public:                                                    }; 
class BallonFoot:  public Ballon { public:                                                   }; 

c)

class Objet                      { public:         void rebondir() { cout <<  "??" << endl; } };
class Porcelaine:  public Objet  { public:         void rebondir() { cout << ":(" << endl; } };
class Ballon:      public Objet  { public:         void rebondir() { cout << ":)" << endl; } };
class BallonRugby: public Ballon { public:         void rebondir() { cout <<  "()" << endl; } };
class BallonFoot : public Ballon { public:         void rebondir() { cout << "O  " << endl; } };

d)

class Objet                      { public:         void rebondir() { cout <<  "??" << endl; } };
class Porcelaine:  public Objet  { public:         void rebondir() { cout <<  ":(" << endl; } };
class Ballon:      public Objet  { public:         void rebondir() { cout << ":)" << endl; } };
class BallonRugby: public Ballon { public: virtual void rebondir() { cout << "()"  << endl; } };
class BallonFoot:  public Ballon { public: virtual void rebondir() { cout << "O "  << endl; } };

e)

class Objet                      { public:         void rebondir() { cout <<  "??" << endl; } };
class Porcelaine:  public Objet  { public: virtual void rebondir() { cout << ":("  << endl; } };
class Ballon:      public Objet  { public: virtual void rebondir() { cout << ":)"  << endl; } };
class BallonRugby: public Ballon { public:         void rebondir() { cout <<  "()" << endl; } };
class BallonFoot:  public Ballon { public:         void rebondir() { cout << "O " << endl; } };

f)

class Objet                      { public: virtual void rebondir() { cout << "??" << endl; } };
class Porcelaine:  public Objet  { public:         void rebondir() { cout <<  ":(" << endl; } };
class Ballon:      public Objet  { public:         void rebondir() { cout <<  ":)" << endl; } };
class BallonRugby: public Ballon { public:         void rebondir() { cout <<  "()" << endl; } };
class BallonFoot:  public Ballon { public:         void rebondir() { cout << "O " << endl; } };