Thursday, July 05, 2007

The right question.

Warning: Technical content included.


The Internet has a whole crap load of information on it... and wading through it can be a difficult task, and is a skill that has to be acquired. Google has made it easier, and for that I respect them.

But it all comes down to asking the right question.

The issue I've been struggling with recently is to do with pure virtual destructors in C++. In my previous job I worked almost exclusively with Java and so my C++ knowledge comes only from uni days... which was pre STL to give a time frame for it. For the last year and a bit I've been working with a mixed C++ and PHP environment... with some legacy Borland Kylix thrown in to give me white hair. Recently I've been trying to work through the design and reimplementation of our backend which I've been trying to do using the best of OO. This means lots of C++ classes and good inheritance models... and trying to understand some of the basics of inheritance coming from a Java background. This means I refer to things as interfaces etc. The main thing with this, I've not really understood is how and when to use virtual destructors. From my understanding if you wanted the equivalent to a Java interface you would declare the class with a pure virtual destructor (virtual ~MyClass() = 0). If I forgot to make the virtual destructor the GNU compiler with -Wall would politely remind me that I hadn't specified a virtual destructor when I had virtual methods. Which I would then do by making the the destructor a pure virtual... which would then give me errors at run time saying that it tried to execute a pure virtual destructor. Also I've been implementing plugin systems (using dlopen) and these would not work with pure virtual destructors. Its all confusing.

So given my ignorance I finally worked out the question to ask - when to use a pure virtual destructor. A quick google came up with this link: http://www.gotw.ca/gotw/031.htm which filled in the missing detail:
If the class should be abstract (you want to prevent instantiating it) but it doesn't happen to have any other pure virtual functions, a common technique to make the destructor pure virtual ...
Of course, any derived class' destructor must call the base class' destructor, and so the destructor must still be defined (even if it's empty):


So in summary the points I learnt as a Java person moving into C++ land:

  1. There is no such things as an Interface in C++ - everything is an abstract class - and that is ok because C++ allows for multiple inheritance

  2. The closest thing to an Interface is a class with only pure virtuals - but you still must have implementation for the destructor!!

No comments: