Multiple inheritance of QObject because of access to deleteLater() method

470 views Asked by At

I use observer-observable pattern in my program. Everything worked before I had to change the code a little. If to be exact I changed the inheritance of IObserver class - right now it inherits QObject:

class IObserver : public QObject
{
...

I did it because of only one thing - I need deleteLater() method to be used in an observer, so I would be able to call implementation of virtual function deinitialization() of IObserver. Thus I could standardize every IObserver message handler.

The problem is, I already inherited QObject (indirectly) in some Observer classes. Like MainForm or AboutDialog. Everything is going fine until I try to call "connect" method in AboutDialog class.

What can I do? I really need this deleteLater() method since I can't use "delete this" in IObserver code - this will call IObserver destructor, not the MainForm or Storage classes for instance.

Thank you.

2

There are 2 answers

2
Guilherme Bernal On BEST ANSWER

I really need this deleteLater() method since I can't use "delete this" in IObserver code - this will call IObserver destructor, not the MainForm or Storage classes for instance.

If you make your destructor virtual (and you should!) it will call the derived destructor just fine. But a problem is that destructing a object while it is handling some signal/slot might cause problems with the event loop. You would have to be very careful with delete this anyway.

The problem is, I already inherited QObject (indirectly) in some Observer classes.

One way you could implement this, not sure if the best thought:

template <typename Derived>
class IObserver
{

    // Just to be sure: (C++11)
    static_assert(is_base_of<Derived, QObject>::value,
                  "must inherit from QObject when using IObserver");

    void deleteMe()
    {
        QObject* thisObject = dynamic_cast<QObject*>(this);
        // no need for check if thisObject equals null. static assert does this.
        thisObject->deleteLater();
    }

};

class MainForm : public IObserver<MainForm>, public QMainWindow
{
    // ...
};

I believe this pattern is called static polymorphism.

1
Marek R On

Abandon inheritance of QObject for IObserver. Instead of that add such method to interface.

class IObserver : public QObject {
public:
   QObject *object() const = 0;
...

Then if implementation of interface inherits the QObject you will return this pointer from object() method. If implementation of interface doesn't inherit QObject you can simply return pointer to some simple QObject which will handle destruction of this object. Then you can simply connect deleteLater for object returned by this method.

Off topic
Use of interfaces for observing in Qt usually is obsolete, slots and signals do this job perfectly and this is more flexible approach.