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.