A virtual destructor is a destructor declared with the virtual keyword in the base class. This ensures that the derived class's destructor is called when deleting an object through a pointer to the base class.
class Base { public: virtual ~Base() { /* ... */ } }; class Derived : public Base { public: ~Derived() override { /* ... */ } }; Base* ptr = new Derived(); delete ptr; // Both destructors will be called
Without a virtual destructor, the behavior may be incorrect — the derived class's destructor will not be called, leading to resource leaks!
Is it necessary to declare the destructor virtual if your base class has no virtual functions?
Answer: Yes, if the class is intended for inheritance with deletion via a pointer to the base type. Even if there are no other virtual functions, the virtuality of the destructor is necessary for the correct deletion of descendants.
class Shape { public: virtual ~Shape() {} };
Story 1
In a large graphics library project, OpenGL resources (buffers, textures) leaked when deleting drawable objects through a pointer to the base class — the corresponding releases were in the destructors of the derived classes, which were not called.
Story 2
In a network library for the TCP protocol, when deleting sessions, the destructor of the descendants managed through a common base interface was not called. This led to widespread socket hangs and exhaustion of descriptor limits.
Story 3
In an embedded system in C++, a wrongly declared (non-virtual) destructor of the base class caused memory leaks for system resources of input-output controllers, and devices failed after several driver update cycles.