Table of Contents

Partie II – Destructeurs

Nous créons les classes suivantes :

class GraphicalObject 
{
    public:       
       virtual void draw () const = 0 ; 
       ~GraphicalObject() { std::cout << "& Delete GraphicalObject \n"; }
 
};
 
class Line: public GraphicalObject 
{
    public:
       virtual void draw () const { std::cout << "Line"; } ; 
       ~Line() { std::cout << "Delete Line\n"; }
 
};
 
class Circle: public GraphicalObject 
{
    public:
       virtual void draw() const { std::cout << " Circle"; } ; 
       ~Circle  () { std::cout << "Delete Circle  \n"; }
 
};

Nous créons le tableau d’objet suivant :

std::vector<GraphicalObject*> createGraphicalObjects(
    int theSize)
{
    std::vector<GraphicalObject*> graphicalObjects(theSize);
    for(int i=0; i < size; i++)
    {
       graphicalObjects[i] = new Line();
       graphicalObjects[++i] = new Circle();
    }
    return graphicalObjects;
}

Nous définissons une fonction de dessin pour l'ensemble des éléments dans le tableau.

void drawGraphicalObjects(std::vector<GraphicalObject*>& theGraphicalObjects)
{
    for(auto it = theGraphicalObjects.begin(); 
        it < theGraphicalObjects.end(); it++)
    {
       (*it)->draw();
    }
}

Nous créons la fonction de destruction du tableau suivante:

void deleteGraphicalObjects(std::vector<GraphicalObject*>& theGraphicalObjects)
{
    for(auto it = theGraphicalObjects.begin(); 
        it < theGraphicalObjects.end(); it++)
    {
       delete *it;
    }
}

Et nous testons avec le code suivant :

auto graphicalObjects = createGraphicalObjects(10);
drawGraphicalObjects(graphicalObjects);
deleteGraphicalObjects(graphicalObjects);

Question n°1

Justifier la sortie produite à l’écran ? Est-ce que c’est le comportement désiré ?

Correction

Correction

Le destructeur appellé est celui de l'objet de base. Nous souhaitons appeller le destructeur de l'objet véritablement détruit et non celui de l'objet de base.

Question n°2

Proposer une modification pour obtenir le comportement souhaité.

Tester après cette modification.

Correction

Correction

Nous déclarons le destructeur dans la classe de base comme étant virtuel.

class GraphicalObject 
{
    public:       
       virtual void draw () const = 0 ; 
       ~GraphicalObject() { std::cout << "& Delete GraphicalObject \n"; }
 
};
 
class Line: public GraphicalObject 
{
    public:
       virtual void draw () const { std::cout << "Line"; } ; 
       ~Line() { std::cout << "Delete Line\n"; }
 
};
 
class Circle: public GraphicalObject 
{
    public:
       virtual void draw() const { std::cout << " Circle"; } ; 
       ~Circle  () { std::cout << "Delete Circle  \n"; }
 
};

Désormais, c'est bien le destructeur de l'objet qui est détruit qui est appellé et pas uniquement le destructeur de la classe de base.