Search code examples
c++qttypedefforward-declarationqlist

Inheriting from a container with non-virtual destructor


I'm trying to use forward declarations and d-pointers to eliminate some include dependencies. Everything is working well, except that I have used XList typedefs for readability in many places (e.g: typedef QList<X> XList).

The workaround for the typedef forward declaration issue is to use inheritance: class XList : public QList<X>{};. QList has a non-virtual destructor. Given the fact that Qt's own QStringList inherits QList<QString> and I'm not allocating XLists on the heap, do you see any problems with this workaround? Should I explicitly disallow heap allocations for the XList classes?


Solution

  • Let's have a look at what will happen if we define XList this way:

    class XList : public QList<X> {};
    

    The following will work as expected:

      XList* x = new XList;
      delete x;
    

    However the following won't:

      QList<X>* q = new XList;
      delete q;
    

    QList<X>'s destructor will be called but not XList's, if any. That's what a virtual destructor in the base class will do for you.

    If you never use heap allocations you should be fine, but you're preparing a trap for the maintainer following you (or even yourself in a few months).

    Make sure this assumption is documented and make XList's new operator private to prevent heap instantiation as you mentioned.

    The safe alternative would be making QList<X> a member of your XList, that is: prefer encapsulation to inheritance.