ProgrammationDéveloppeur C++

Qu'est-ce qu'un destructeur virtuel en C++ et à quoi sert-il ? Donnez un exemple de comportement incorrect en l'absence de destructeur virtuel.

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Un destructeur virtuel est un destructeur déclaré avec le mot clé virtual dans la classe de base. Cela garantit que le destructeur de la classe dérivée est appelé lors de la suppression d'un objet via un pointeur vers la classe de base.

class Base { public: virtual ~Base() { /* ... */ } }; class Derived : public Base { public: ~Derived() override { /* ... */ } }; Base* ptr = new Derived(); delete ptr; // Les deux destructeurs seront appelés

Sans destructeur virtuel, le comportement peut être incorrect — le destructeur de la classe dérivée ne sera pas appelé, ce qui entraînera une fuite de ressources !


Question piège.

Faut-il déclarer un destructeur virtuel si votre classe de base n'a aucune fonction virtuelle ?

Réponse : Oui, si la classe est destinée à être héritée avec suppression via un pointeur vers le type de base. Même s'il n'y a pas d'autres fonctions virtuelles, la virtualité du destructeur est nécessaire pour garantir la suppression correcte des descendants.

class Shape { public: virtual ~Shape() {} };

Exemples d'erreurs réelles dues à une méconnaissance des subtilités du sujet.


Histoire 1

Dans un grand projet de bibliothèque graphique, lors de la suppression d'objets de dessin via un pointeur vers la classe de base, des ressources OpenGL (tampons, textures) fuyaient — les libérations correspondantes se trouvaient dans les destructeurs des classes dérivées, mais elles n'étaient pas appelées.


Histoire 2

Dans une bibliothèque réseau pour le protocole TCP, lors de la suppression des sessions, le destructeur des héritiers, gérés via une interface de base commune, n'a pas été appelé. Cela a conduit à des blocages massifs de sockets et à l'épuisement des limites de descripteurs.


Histoire 3

Dans un système embarqué en C++, un destructeur mal déclaré (non-virtual) de la classe de base a provoqué une fuite de mémoire pour les ressources système des contrôleurs d'entrée-sortie, les dispositifs devenant défaillants après plusieurs cycles de mise à jour des pilotes.