Lesson 153 +10 XP

Virtual Destructors

Virtual Destructors

When you delete an object through a base pointer, the wrong destructor might run. Making the base destructor virtual fixes it, and that fix prevents real memory leaks.

The problem

If you delete a derived object through a base pointer and the destructor is not virtual, only the base destructor runs:

class Base {
public:
  ~Base() { cout << "Base destroyed"; }
};

class Derived : public Base { };

Base* b = new Derived();
delete b;   // prints "Base destroyed"

The Derived part never had a chance to clean up. Resources owned by the derived class are leaked.

The fix: a virtual destructor

Mark the base destructor virtual:

class Base {
public:
  virtual ~Base() { cout << "Base destroyed"; }
};

Now delete b dispatches correctly: ~Derived() runs first, then ~Base(). Both parts are cleaned in the right order.

When it matters

  • If a class is meant to be used polymorphically, give it a virtual destructor.
  • If it is only used by value or never as a base, a plain destructor is fine.
  • Rule of thumb: any class with virtual functions should get a virtual destructor.

TL;DR

  • Without a virtual destructor, deleting via a base pointer runs only the base's destructor.
  • Mark the base destructor virtual.
  • With the fix, the derived destructor runs, then the base's.
  • Polymorphic bases should have a virtual destructor.
  • It is the last chance to release resources correctly.