I am an experienced C programmer, who is just learning C++. I have a base class CVListView (which is a wrapper around the Windows virtual listview control), and a derived class CTerminal, which basically adds some console-type concepts to the CVListView, such as console rows/columns, current cursor position, etc. The base class can be instantiated on its own, or via the derived class. I have destructors in both classes, though the destructor in the derived class doesn't actually do anything, in this example.
All was fine until I ran the code through PcLint, which warned me that there was no "virtual destructor" in the base class. I did some reading on virtual destructors, then added "virtual" to the base-class destructor, PcLint was happy, and the program still seems to run properly.
However, I really don't understand what the purpose of this was, and am hoping someone can explain it to me more clearly. The one commented example that I found, was explaining something about how 'virtual' was needed if you used a pointer to the base class to access a derived class:
CTerminal *T = new CTerminal() ;
CVListView *v = T ;
Then, if I call:
delete v ;
then which destructor is called depends on whether the base-class destructor is virtual or not.
There are several things I don't understand here... first of all, why would I ever do this?? If I want the base class, I'll instantiate CVListView. If I want the derived class, I'll instantiate CTerminal. I don't see any reason that I would *ever* use the base-class pointer to point to the derived class... ???
Could someone try to explain this to me, in a way that a 25-year C programmer could understand?? I would be *very* grateful !!
To store "heterogeneous" objects in a container (such as an array), is one reason. To use the built-in runtime polymorphism is another. To support extensibility is yet another.
Okay, I understand that... actually, I don't know what polymorphism is yet, but I can see having an array of "base class" elements, which are all actually instances of various derived classes. Doesn't easily apply in my example above, but in the classic Shapes example, I can understand easily. Thanks!
In a nutshell, you want a virtual destructor if you are using derived classes through a base pointer.
1 2
Employee* e = new Manager;
delete e;
If you didn't have a virtual destructor in Employee, Manager's destructor would not be called because you are deleting it from the base class. Only Employee's destructor would be called. *Any method not declared virtual in the base class will be compile time. That means it will always be the method of the type and not what it is pointing to at runtime.
Edit - if you are wondering why you would ever use a Base class pointer the perfect example is if you wanted to create a wrapper class for an inheritance hierarchy.
That wrapper class would consist of a single Base class pointer as it's data. It would then contain every available public method throughout the hierarchy and would dynamically cast it's pointer whenever it needed to call a non-polymorhphic method in a derived class.
That way, the user never has to worry about it and can use pointers to the wrapper class with ease.