Should destructors always be virtual in polymorphic classes?

Question | Aug 15, 2019 | nwheeler 

The instances of derived polymorphic classes are often accessed through their base class references or pointers. If a class has defined a destructor, which releases some resources, it is essential to make sure that this destructor is invoked when an instance is deleted through its base class pointer. We can ensure that a proper derived-class destructor is always invoked by marking the destructors virtual.

Let's take an example. The classes Base and Derived are polymorphic because the Base::foo is virtual:

class Base {
public:
  virtual void foo() {}
  ~Base() {  // destructor not virtual 
      std::cout << "Base"; 
     // release some resources
  }
}; 

class Derived : public Base {
public:
  void foo() override { /*..*/ } // override virtual foo
  ~Derived() { // destructor not virtual
     std::cout << "Derived "; 
     // release some resources
  }
};

A function useAndThrow takes a Base pointer, calls foo on it, and deletes the instance:

void useAndThrow(Base* ptrBase) {
   ptrBase->foo();
   delete ptrBase; // Problem
}

The useAndThrow is called on a Derived instance as:

useAndThrow(new Derived());

We know that a derived class destructor always calls its base class destructor. So in order to properly free the resources in both Derived and Base, the ~Derived() should be invoked when delete ptrBase is called in useAndThrow. However, in this case only ~Base() is invoked causing some resource leak in Derived.

Which one of the following would ensure that the ~Derived() is invoked by delete ptrBase?

2015 nextptr