Qt多重继承和信号

Rvd*_*vdK 7 c++ qt multiple-inheritance qt-signals

由于QObject,我遇到了关于多重继承的QT问题.我知道其他很多人都有同样的问题,但我不知道应该怎么解决.

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

    ...
}
Run Code Online (Sandbox Code Playgroud)

当我这样做

MainMenuOption* messages = new MainMenuOption();
connect(messages, SIGNAL(selected()), SLOT(onMenuOptionSelected()))
Run Code Online (Sandbox Code Playgroud)

我会得到错误:

QObject'是'MainMenuOption'的模糊基础

之所以我让NavigatableItem因为信号而来自QObject.有没有办法做到这一点?

编辑:

为每个继承声明添加虚拟,仍然给我同样的错误:

class NavigatableItem : public virtual QObject

class Button : public virtual NavigatableItem, public virtual QToolButton

class MainMenuOption : public virtual Button
Run Code Online (Sandbox Code Playgroud)

即使在'全部清洁'之后,'运行qmake'和'全部建立'.

Dav*_*eer 8

它需要更多的代码,但我过去所做的就是使其中一个(NavigatableItem在这种情况下)你是一个纯虚拟类,即接口.而不是使用"信号"宏,使它们成为纯虚拟保护功能.然后从您的QObject派生类和接口中多次继承,并实现这些方法.

我知道它有点争议,但不惜一切代价避免多次实现继承确实解决了许多问题和困惑.在谷歌C++风格指南推荐这个,我认为这是很好的建议.

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();
        ...
}
Run Code Online (Sandbox Code Playgroud)

  • 你将不得不重新定义它们,但你不必重新实现它们.通常有一种方法可以将它们放在一些公共类(可能只是一个实用类)中,将它作为继承类的私有成员包含在内,并使你的继承类具有'has-a'关系而不是'is-a'. - 一个'关系.是的,这是一些额外的代码,但您的实际业务逻辑通常可以保存在一个位置,以避免"复制和粘贴"错误.我发现避免多重继承的其他问题是值得的,但我很乐意承认这仅仅是一种意见. (2认同)