next up previous contents
Next: Opérateurs membres Up: Initialisation et constructeurs Previous: Fonction de conversion

Destructeurs

La destruction des objets est un problème parfois délicat. Comme on peut définir ses propres constructeurs, il faut aussi définir le moyen de détruire ce qu'ils ont créé. C'est le cas, par exemple, quand le constructeur fait de l'allocation dynamique.

Le compilateur génère automatiquement le ``code'' nécessaire à la destruction de l'objet quand cet objet n'est plus accessible, comme, par exemple, pour un objet local à une fonction après le retour dans le programme appelant. Par défaut (en l'absence d'un destructeur), le compilateur n'a rien à faire, l'allocation ayant eu lieu sur la pile d'exécution.

Un destructeur est une fonction membre de nom ~X (X étant le nom de la classe). Son but est de détruire les valeurs de type X avant que l'objet les contenant ne le soit. Un destructeur est l'inverse d'un constructeur.

// tableau d'entiers
class tab_ent{
public:
  tab_ent(int n){
    t=new int[taille=n];
    assert(t != 0);
  }
  ~tab_ent(){
    delete [] t;
  }
  //...
private:
  int *t;
  int taille;
}
Si un destructeur n'avait pas été défini pour tab_ent, quand un objet tab_ent est détruit, l'allocation qui avait été réalisée pour le membre t reste.

Un destructeur est appelé quand:

Pour des raisons évidentes, le corps d'un destructeur est exécuté avant les destructeurs pour les objets membres (ordre inverse des constructeurs).

Les destructeurs peuvent être virtuelsgif, mais ils ne le sont pas par défaut.

La gestion dynamique de la mémoire est un problème délicat. Pour des raisons d'efficacité, il faut éviter la recopie, mais alors il faut définir une stratégie pour libérer la mémoire...

struct item{
  char *data;
  item *suivant;
  //...

};
item a;  
class liste{
  //
public:
  //...
  ~liste();
};
Que doit faire le ~liste(), doit-il libérer les data des item : si oui cela suppose qu'il n'y a pas de partage et qu'on n'a pas eu d'affectation du genre a.data="bonjour"gif, d'un autre côté, il faut bien libérer l'espace alloué. Il n'y a pas de solution générale. Une solution serait d'avoir une gestion de la mémoire avec ``ramasse miettes''. Ce n'est pas la solution choisie par le C++, en C++ c'est à l'utilisateur de gérer la mémoire.


next up previous contents
Next: Opérateurs membres Up: Initialisation et constructeurs Previous: Fonction de conversion


Mon Oct 20 14:02:48 MET 1997