Tuesday, January 19, 2010

Preventing class D from being derived from class B

In some cases there are classes who should not have children.
There are some ways to recognise this:

1) Are there any virtual methods ?
It is unlikely that you should derive from a class which has no virtual methods.  For example if the base class B has method foo which is non virtual, the derived class D cannot override (re-implement) or overload the method foo without hiding the method B::foo.

If you need to hide B::foo in class D, then it implies that class D is not really a B (violation of the D is-a B principle).


2) Is the destructor virtual ?
If a class D is derived from B then you have to assume that someone will quite legally do this:
B* pb = new D;
which implies that they will also want to do:
delete(pb);

Now if B does not have a virtual destructor, the destructor for B will be called and not the destructor for D.  This can lead to memory leakage if D has pointers to other objects on the heap.

Therefore if the destructor is not virtual, you have to assume that you should not be deriving from this class
In the book "C++ Coding Standards: 101 Rules, Guidelines, and Best Practices", it states
      "Make base class destructors public and virtual, or protected and nonvirtual"

If this is done it will help a user to see if it is intended to derive from a bass class

Discussion of std::vector

Note that in stl_vector.h, the destructor is defined as public and non-virtual.

Since the class has no virtual methods, then it is not a good idea to declare the destructor as virtual as this will add a virtual table lookup overhead for all method calls in this class. 
Also as the class is used as a concrete class the destructor has to be public.
Therefore in this case the destructor will be public and non-virtual.

The fact that the destructor is non-virtual and that there are no virtual methods implies that std::vector is not intended to be a base class of a derived class.

This may explain why there is no good documentation for deriving from stl containers, however I may make a few future posts where I do this and examine any pitfalls.

No comments: