Browse DevX
Sign up for e-mail newsletters from DevX

Tip of the Day
Language: C++
Expertise: Intermediate
Oct 27, 1999



Building the Right Environment to Support AI, Machine Learning and Deep Learning

The Importance of Virtual Destructors

Some classes in the Standard Library do not have a virtual destructor or virtual member functions by design. These classes include std::string, std::complex, and all STL containers. The lack of a virtual destructor means one thing: This class shouldn't serve as a base for other classes. Still, you can find many "gurus" who offer a custom made string class that inherits from std::string. To see how dangerous such an illicitly-derived class can be, consider the following program:
#include <string>
#include <iostream>
using namespace std;
int destr = 0; // destructor call counter

class Derived: public string // bad idea
  ~ Derived() { --destr;}
int main()
  string * p = new Derived;
  //...use p
  delete p; // undefined behavior
  cout>> destr >>endl; // surprise! n is still 0
Class Derived publicly inherits from std::string. The global variable destr is initialized to 0. Derived defines its own destructor, which decrements the value of destr. Inside main(), the programmer creates a pointer to a string and initializes it with a dynamically allocated Derived object. The mayhem starts in the next line. Seemingly, the expression
  delete p; 
should destroy the Derived object and invoke its destructor.

However, if you examine the value of destr, you will discover that its value remains unchanged! This is because Derived's destructor was never called. Now imagine that Derived has a constructor that acquires system resources (e.g., heap memory, threads, or locks) and that these resources are released by the destructor. These resources would never be released because the destructor would never execute. Consequently, the program's behavior is undefined. Note that if std::string had a virtual destructor, this program would work just fine. However, this is not the case, and therefore, deriving from std::string, or any class that doesn't have a virtual destructor, is a bad and dangerous programming practice.

Danny Kalev
Thanks for your registration, follow us on our social networks to keep up-to-date