Search code examples
c++qtmultiple-inheritanceqt-signals

Qt multiple inheritance and signals


I'm having a problem with QT regarding multiple enheritance because of QObject. I know that a lot of others have the same problems but I don't know how I should fix it.

class NavigatableItem : public QObject
{
    Q_OBJECT

    signals:
        void deselected();
        void selected();
        void activated();
};

class Button : public NavigatableItem, public QToolButton
{
    Q_OBJECT

    ...
}

class MainMenuOption : public Button
{
    Q_OBJECT

    ...
}

When I do this

MainMenuOption* messages = new MainMenuOption();
connect(messages, SIGNAL(selected()), SLOT(onMenuOptionSelected()))

I will get the error:

QObject' is an ambiguous base of 'MainMenuOption'

The reason why I let NavigatableItem enherit from QObject because of the signals. Is there a way to do this?

Edit:

Adding virtual to each inheritence declaration, still gives me the same error:

class NavigatableItem : public virtual QObject

class Button : public virtual NavigatableItem, public virtual QToolButton

class MainMenuOption : public virtual Button

Even after a 'clean all', 'run qmake' and 'build all'.


Solution

  • It requires a bit more code, but what I have done in the past is make one of them (your NavigatableItem in this case) a pure virtual class, i.e. interface. Instead of using the "signals" macro, make them pure virtual protected functions. Then multiply-inherit from your QObject-derived class as well as the interface, and implement the methods.

    I know it is somewhat controversial, but avoiding multiple implementation inheritance at all costs does solve a host of problems and confusion. The Google C++ Style Guidelines recommend this, and I think it is good advice.

    class NavigatableItemInterface
    {
        // Don't forget the virtual destructor!
        protected:
            virtual void deselected() = 0;
            virtual void selected() = 0;
            virtual void activated() = 0;
    };
    
    class Button : public NavigatableItemInterface, public QToolButton
    {
        Q_OBJECT
        ...
        signals:
            virtual void deselected();
            ...
    }