next up previous contents
Next: Héritage Up: Initialisation et constructeurs Previous: Opérateurs new et delete

Destructions et héritage

Grâce à l'héritage, un objet d'une classe dérivée peut être considéré comme étant un objet de la classe de base, pour la destruction de l'objet cela peut poser certains problèmes :

#include <iostream.h>
class base{
    char *s;
public:
    base(){
        s=new char [100];
    }
    virtual ~base(){
        delete [] s;
    }
};
class derivee: public base{
    char *t;
public:
    derivee(){
        t=new char [100];
    }
    ~derivee(){ 
        delete [] t;
    }
 };
    

void main()
{
    base* pa=new derivee;
    delete pa;
}
Si ~base() n'était pas virtuel, delete pa détruirait uniquement la partie base de *pa, alors qu'ici ~derivee() puis ~base() seront appelé.

De même :

class base{
    char *s;
public:
    base(){
        s=new char [100];
    }
    void *operator new(size_t t){
        cout<<"base::new()\n";
        return ::operator new(t);
    }
    void operator delete(void * s){
        cout<<"base::delete()\n";
        ::operator delete(s);
    }

    virtual ~base(){
        cout<<"~base()"<<endl;
        delete [] s;
    }
};
class derivee: public base{
    char *t;
public:
    derivee(){
        t=new char [100];
    }
    void *operator new(size_t t){
        cout<<"derivee::new()\n";
        return ::operator new(t);
    }
    void operator delete(void * s){
        cout<<"derivee::delete()\n";
        ::operator delete(s);
    }
    ~derivee(){
        cout<<"~derivee()"<<endl;
        delete [] t;
    }
 };
    

void main()
{
    base* pa=new derivee;
    delete pa;
}
fera ce qu'il faut : le destructeur étant virtuel, c'est bien derivee::operator delete qui sera appelé. En effet, delete appelle d'abord implicitement le destructeur de la classe et le delete appelé sera celui correspondant à la liaison dynamique du destructeur.




Mon Oct 20 14:02:48 MET 1997