The reason why your class' constructor should usually be virtual:

class base {
 public: 
  base (){ /* constructor */ }
  ~base () { /* Non-virtual destructor */ }
};
class derived : public base {
 public:
  derived () { /* constructor */ }
  ~derived () { /* destructor */ }
 private:
  char aLongCstring[1024];
};
int main () {
  base* aPointer = new derived;
  delete aPointer;
  return 0; // even in example programs!
}

What's so bad? Well, aPointer is assigned a new derived. New calls derived's constructor, which allocates 1024 bytes of data for the variable. Then delete is called. All delete knows is that it is being passed a base* -- so it calls base's destructor. But base's destructor doesn't know about the 1024 bytes of data, so it doesn't delete them -- and we have a memory leak. That's a kilobyte down the bit bucket until your program ends -- or, if you go into an infinite loop, until you restart the computer. If you allocated an array of 1024 deriveds, it'd be a megabyte lost. Do this a few times and you'll have major problems.

The solution? Make ~base virtual. Then the compiler knows that whenever the destructor is being called on an object of type base, it should check to see if the object is really of another class with base as its base type -- which it is, in this case. So ~derived gets called, which knows about the 1024 bytes, and everything is sunshine and rainbows.


Which leads to the question, why would you ever NOT make a destructor virtual? Well, you might want a non-virtual destructor if 2 things are the case:

1. The class is very small.
2. The class is not intended to be used as the base class of another class, and therefore has no other virtual functions.

But why, you ask? Simple. If a class has any virtual member functions, the compiler adds an extra data member -- a pointer -- which keeps track of what the actual class of the instantiated object is, so that the correct version of a function can be called at runtime, even by a function that doesn't know about the details of derived classes. This pointer takes up 4 bytes on most systems. Therefore, if the class is very small (maybe it only stores a one-byte character), you've just increased the size of the class significantly (from one byte to 5.) If a class has no other virtual functions, a non-virtual destructor saves these four bytes.

Since when do four bytes matter? Well, suppose someone has an array of your class. A big array. Maybe they have, say, 128 million of them. If your class takes up one byte, that's 128 megabytes of memory -- which most computers can handle. But if you take up 5 bytes, that becomes 640 megabytes -- which some computers cannot. (I know, I know, your computer has several gigabytes of RAM. Scale up the number accordingly.)

Is this an obscure reason? Yes. Is it a valid reason? Also yes. Is it a reason that will ever occur in your career as a programmer? Maybe, maybe not. But you should keep it in mind.

But, you say, you want to keep your class small and use a non-virtual destructor, but you're still worried about the scenario outlined above? ...Well, put a comment in your header file telling people not to derive classes from your class without editing your class to have a virtual destructor. There's no language mechanism to stop them, though. Sorry.