Utilité du destructeur virtuel

Description

Ce code permet de comprendre l'utilité du destructeur virtuel. Il présente les 2 comportements différents obtenus en utilisant un destructeur virtuel et sans l'utiliser.

Le zip contient un projet CodeBlocks. Si vous utilisez un autre logiciel, il suffit de récupérer simplement le CPP.

Source / Exemple :


#include <iostream>

// On se sert de UneClasse pour observer le comportement de l'allocation et de la désollaction d'un objet dynamique au sein d'une autre classe (ici, A, B, C et D)
class UneClasse
{
public:
    UneClasse()
    {
        std::cout << "Construction UneClasse" << std::endl;
    }
    ~UneClasse()
    {
        std::cout << "Destruction UneClasse" << std::endl;
    }
};

class A
{
private:
    UneClasse* UnObjet;
    
public:
    A()
    {
        std::cout << "Construction A" << std::endl;
        UnObjet=new UneClasse();
    }
    ~A()  // DESTRUCTEUR NON VIRTUEL
    {
        std::cout << "Destruction A" << std::endl;
        if(UnObjet!=NULL)
            delete UnObjet;
    }
    virtual void QuiSuisJe()
    {
        std::cout << "Je suis A" << std::endl;
    }
};

class B:public A
{

public:
    B()
    {
        std::cout << "Construction B" << std::endl;
    }
    ~B()
    {
        std::cout << "Destruction B" << std::endl;
    }
    virtual void QuiSuisJe()
    {
        std::cout << "Je suis B" << std::endl;
    }
};

class C
{
private:
    UneClasse* UnObjet;
    
public:
    C()
    {
        std::cout << "Construction C" << std::endl;
        UnObjet=new UneClasse();
    }
    virtual ~C() // DESTRUCTEUR VIRTUEL
    {
        std::cout << "Destruction C" << std::endl;
        if(UnObjet!=NULL)
            delete UnObjet;
    }
    virtual void QuiSuisJe()
    {
        std::cout << "Je suis C" << std::endl;
    }
    
};

class D:public C
{

public:
    D()
    {
        std::cout << "Construction D" << std::endl;
    }
    ~D()
    {
        std::cout << "Destruction D" << std::endl;
    }
    virtual void QuiSuisJe()
    {
        std::cout << "Je suis D" << std::endl;
    }
};

int main()
{
    A *a=new A();
    delete a;
    
    std::cout << std::endl;
    
    B *b=new B();
    delete b;
    
    std::cout << std::endl;
    
    C *c=new C();
    delete c;
    
    std::cout << std::endl;
    
    D *d=new D();
    delete d;
    
    std::cout << std::endl;
       
    A * a_B = new B();   // construction de A et B mais attribution du pointeur à un objet de type A
    a_B->QuiSuisJe();    // affiche "Je suis B"
    delete a_B;          // On s'aperçoit sur la console que la partie B n'est pas détruite
    
    std::cout << std::endl;
    
    C * c_D = new D();   // construction de C et D mais attribution du pointeur à un objet de type C
    c_D->QuiSuisJe();    // affiche "Je suis D"
    delete c_D;          // On s'aperçoit sur la console que C et D sont bien détruits
    
    return 0;
}

Conclusion :


Pour bien comprendre, le mieux c'est d'exécuter le code soi-même...

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.