
FAQ C++Consultez toutes les FAQ
Nombre d'auteurs : 34, nombre de questions : 368, derni�re mise � jour : 14 novembre 2021 Ajouter une question
Cette FAQ a �t� r�alis�e � partir des questions fr�quemment pos�es sur les forums de http://www.developpez.com et de l'exp�rience personnelle des auteurs.
Je tiens � souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes ; les auteurs font le maximum, mais l'erreur est humaine. Cette FAQ ne pr�tend pas non plus �tre compl�te. Si vous trouvez une erreur ou si vous souhaitez devenir r�dacteur, lisez ceci.
Sur ce, nous vous souhaitons une bonne lecture.
- Qu'est-ce qu'un destructeur ?
- Quand dois-je d�finir un destructeur ?
- Pourquoi et quand faut-il cr�er un destructeur virtuel ?
- Est-il possible d'invoquer explicitement le destructeur d'une classe ?
- Dans quel ordre les objets locaux sont-ils d�truits ?
- Dans quel ordre les objets contenus dans un tableau sont-ils d�truits ?
- Doit-on d�truire explicitement les objets locaux ?
- Et si on veut absolument qu'un objet local � meure � avant l'accolade fermant le bloc dans lequel il a �t� cr�� ?
- Et s'il n'est pas possible de placer l'objet local dans un bloc artificiel ?
- Peut-on d�truire explicitement un objet allou� par new ?
- Dans le code d'un destructeur, doit-on d�truire explicitement les objets membres ?
- Dans le code du destructeur d'une classe d�riv�e, doit-on appeler explicitement le destructeur de la classe de base ?
Un destructeur est ce qui d�truit un objet, lib�re la m�moire allou�e dans le constructeur ou ce qui n'a pas �t� lib�r� durant la vie de l'objet.
Il porte le m�me nom que la classe pr�c�d� du signe ~.
Un destructeur ne prend aucun param�tre et ne renvoie aucune valeur de retour. Sa d�claration se fait de la fa�on suivante�:
Code c++ : | S�lectionner tout |
1 2 3 4 5 | class MaClasse { // ... ~MaClasse(); }; |
Le destructeur est appel� pour lib�rer les ressources acquises par un objet lorsque l'espace occup� par celui-ci doit �tre lib�r� :
Code c++ : | S�lectionner tout |
1 2 3 4 5 | class CMyClass { public: ~CMyClass();// destructeur }; |
Si on doit utiliser la classe comme base dans un h�ritage pour une utilisation polymorphe (utilisation via une r�f�rence ou un pointeur sur la base), alors la classe de base doit d�finir un destructeur virtuel.
Il est n�cessaire de rendre le destructeur d'une classe de base virtuel quand celle-ci est destin�e � �tre d�truite polymorphiquement. G�n�ralement d�s qu'un objet commence � �tre utilis� polymorphiquement (c'est-�-dire utilis� en place d'un objet de la classe m�re), il est fr�quent qu'il soit stock� et manipul� via un pointeur vers sa classe m�re, comme dans l'exemple suivant :
Code c++ : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include <iostream> // classe de base A destin�e � �tre d�riv�e class A { public: A() { std::cout << "Constructeur de A.\n"; } ~A() { std::cout << "Destructeur de A.\n"; } virtual void PrintName() { std::cout << "Classe A.\n"; } }; // B h�rite de A class B : public A { public: B() { std::cout << "Constructeur de B.\n"; } ~B() { std::cout << "Destructeur de B.\n"; } virtual void PrintName() { std::cout << "Classe B.\n"; } }; int main() { // utilisation polymorphe de B A * a = new B; // construction de A et B a->PrintName(); // affiche "Classe B" delete a; // destruction de A mais pas de B ! } |

Le code pr�c�dent compil� avec Visual C++ 7.1 produit le r�sultat suivant :
Code : | S�lectionner tout |
1 2 3 4 | Constructeur de A. Constructeur de B. Classe B. Destructeur de A. |
Code c++ : | S�lectionner tout |
1 2 3 4 5 6 7 8 | class A { public: A() { std::cout << "Constructeur de A.\n"; } virtual ~A() { std::cout << "Destructeur de A.\n"; } virtual void PrintName() { std::cout << "Classe A.\n"; } }; |
Rendre un destructeur virtuel ou non ne se limite donc pas � l'ajout du mot-cl� virtual mais doit �tre l'aboutissement d'une r�flexion men�e sur l'utilisation de la classe. Une classe qui n'est pas destin�e � �tre d�riv�e n'a pas � avoir de destructeur virtuel.
Oui, il est possible d'appeler explicitement le destructeur d'une classe, bien que ce soit une pratique � proscrire. La raison en est simple : il est appel� automatiquement par le compilateur lorsque l'objet va �tre d�truit, et ce, que vous l'ayez appel� ou non. Autrement dit, dans le code suivant :
Code c++ : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <iostream> class Test { public: ~Test() { std::cout << "Destruction\n"; } }; int main() { Test t; t.~Test(); // appel explicite du destructeur } // ici, le compilateur appelle � nouveau le destructeur |
L'un des seuls cas o� l'on doit appeler le destructeur explicitement est lorsqu'on a utilis� l'op�rateur new de placement pour cr�er le m�me objet. Dans ce cas, de m�me qu'on s'est substitu� au compilateur pour g�rer la vie de l'objet, il faut faire le travail jusqu'au bout et g�rer sa destruction. Voir � ce sujet

Dans l'ordre inverse de celui dans lequel ils ont �t� construits : le premier objet construit est le dernier d�truit.
Dans l'exemple ci-dessous, le destructeur de b sera ex�cut� en premier, suivi du destructeur de a :
Code c++ : | S�lectionner tout |
1 2 3 4 5 6 | void userCode() { Fred a; Fred b; // ... } |
Dans l'ordre inverse de celui dans lequel ils ont �t� construits : le premier objet construit est le dernier d�truit.
Dans l'exemple ci-dessous, l'ordre des destructions est a[9], a[8], a[1], a[0] :
Code c++ : | S�lectionner tout |
1 2 3 4 5 | void userCode() { Fred a[10]; // ... } |
Surtout pas !
Car le destructeur sera appel� une deuxi�me fois au niveau de l'accolade fermant le bloc dans lequel l'objet a �t� cr��. La norme C++ le garantit et vous ne pouvez rien faire pour emp�cher que �a arrive ; c'est automatique. Et �a risque de vraiment tr�s mal se passer si le destructeur d'un objet est appel� deux fois de suite.
Il suffit de limiter la dur�e de vie de l'objet local en le pla�ant dans un bloc { ... } artificiel :
Code c++ : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 | void someCode() { { File f; // ... [Ici, le fichier est encore ouvert] ... } // Ici, le destructeur de f est appel� automatiquement ! // ... [Le code ici s'ex�cutera apr�s que f soit ferm�] ... } |
Dans la plupart des cas, il est possible de limiter la dur�e de vie d'un objet local en le pla�ant dans un bloc artificiel ({ ... }) .Si, pour une raison ou pour une autre, ce n'est pas possible, ajoutez � la classe une fonction membre qui a le m�me effet que le destructeur. Mais n'appelez pas le destructeur vous-m�me !
Dans le cas de File, par exemple, vous pourriez ajouter � la classe une fonction membre close(). Le destructeur se contenterait simplement d'appeler cette fonction. Notez que la fonction close() aura besoin de marquer l'objet File de fa�on � ne pas tenter de fermer le fichier s'il l'est d�j�, ce qui peut se produire si close() est appel�e plusieurs fois. L'une des solutions possibles est de donner � la donn�e membre fileHandle_ une valeur qui n'a pas de sens, par exemple -1, et de v�rifier � l'entr�e de la fonction que fileHandle_ n'est pas �gale � cette valeur :
Code c++ : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class File { public: void close(); ~File(); // ... private: int fileHandle_; // fileHandle_ >= 0 seulement si le fichier est ouvert }; File::~File() { close(); } void File::close() { if (fileHandle_ >= 0) { // ... [Utiliser les appels syst�mes qui conviennent pour fermer le fichier] ... fileHandle_ = -1; } } |
Dans la plupart des cas, NON.
� moins que vous ayez utilis� placement new, utilisez delete plut�t que d'appeler explicitement le destructeur de l'objet. Imaginez par exemple que vous ayez allou� un objet gr�ce � une � new expression � classique :
Code c++ : | S�lectionner tout |
Fred* p = new Fred();
Code c++ : | S�lectionner tout |
delete p; // p->~Fred() est appel� automatiquement
Non. Il n'est jamais n�cessaire d'appeler explicitement un destructeur (sauf si l'objet a �t� cr�� avec un placement new).
Le destructeur d'une classe (il existe m�me si vous ne l'avez pas d�fini) appelle automatiquement les destructeurs des objets membres. Ces objets sont d�truits dans l'ordre inverse de celui dans lequel ils apparaissent dans la d�claration de la classe.
Code c++ : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class Member { public: ~Member(); // ... }; class Fred { public: ~Fred(); // ... private: Member x_; Member y_; Member z_; }; Fred::~Fred() { // Le compilateur appelle automatiquement z_.~Member() // Le compilateur appelle automatiquement y_.~Member() // Le compilateur appelle automatiquement x_.~Member() } |
Non. Il n'est jamais n�cessaire d'appeler explicitement un destructeur (sauf si l'objet a �t� cr�� avec un placement new).
Le destructeur d'une classe d�riv�e (il existe m�me si vous ne l'avez pas d�fini) appelle automatiquement les destructeurs des sous-objets des classes de base. Les classes de base sont d�truites apr�s les objets membres. Et dans le cas d'un h�ritage multiple, les classes de base directes sont d�truites dans l'ordre inverse de celui dans lequel elles apparaissent dans la d�claration d'h�ritage.
Code c++ : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | class Member { public: ~Member(); // ... }; class Base { public: virtual ~Base(); // Un destructeur virtuel // ... }; class Derived : public Base { public: ~Derived(); // ... private: Member x_; }; Derived::~Derived() { // Le compilateur appelle automatiquement x_.~Member() // Le compilateur appelle automatiquement Base::~Base() } |
Proposer une nouvelle r�ponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plut�t sur le forum de la rubrique pour �aLes sources pr�sent�es sur cette page sont libres de droits et vous pouvez les utiliser � votre convenance. Par contre, la page de pr�sentation constitue une �uvre intellectuelle prot�g�e par les droits d'auteur. Copyright � 2025 Developpez Developpez LLC. Tous droits r�serv�s Developpez LLC. Aucune reproduction, m�me partielle, ne peut �tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'� trois ans de prison et jusqu'� 300 000 � de dommages et int�r�ts.