Pixelate:Issue 14/The Virtues of Virtual Deconstructors

From Allegro Wiki

Jump to: navigation, search
Scripting
Original author: Crhis Barry (aka 23yrold3yrold)
some mail
Website:
zip:

The Virtues of Virtual Deconstructors

This is a short article intended for the extra-newbish C++ coder, and shows a detail of inheritance one should be aware of when one is using polymorphism.

Polymorphism, from a C++ perspective, is what happens when you start changing what different derived objects do in different contexts. For example, when you create a CShape class with a virtual drawing function, then derive CCircle and CSquare classes that implement that drawing function in two different ways, that's polymorphism. You can treat both objects like a CShape (as you should, because that's what they are), but how they actually draw themselves is specific to the class. This is done using pointers:


   CShape *shape = new CCircle;
   shape->Draw();

Now I'm not going to get into all the details of pointers and inheritance. I'm just going to make some mentions of what you should be aware of concerning the constructors and destructors here. Something not obvious to the budding new programmer is that both CShape's and CCircle's constructors are called here. CShape's constructor isn't called explicitly unless you do so in CCircle's initialization list (and if CShape has no default constructor, you have to do just that), but even if you don't, the default constructor is called implicitly. Constructors are always called in order from the base class down. So CShape's constructor is called before CCircle's.

Now, it might follow that the opposite is true, that destructors will get called when you delete the object; CCircle's first and then CShape. But no. That will only happen if you declare the destructor virtual. If not, the behavior is undefined, though the general result is that the derived class's destructor is never called. Now, it seems like you wouldn't expect that to be the default behavior. But there are times that a virtual destructor is undesirable so always make your destructor virtual if you plan to derive other classes from it. Times you might not want the destructor virtual might be if you want to discourage deriving new classes from the pre-existing one. Some of the STL classes do this, if I'm not mistaken. If a class has no virtual functions, it's usually an indication that it's not meant to be used as a base class, and therefore that it doesn't need a virtual destructor.


   class CShape {
      public:
         CShape();
         ~CShape();

      ....
   };

Of course, if your destructors and constructors are set up well, then anything allocated or set up in a class's constructor gets deallocated and uninitalized in the same class's destructor. Making sure the necessary destructors are virtual will ensure classes can be relied upon not to leak memory or otherwise fail to act as you intended, no matter how much you derive from them.

All for now. See you next issue.

Personal tools