Qt多重继承和信号

8

我在使用QT时遇到了关于多重继承的问题,由于QObject的存在。我知道很多人也遇到了同样的问题,但是我不知道应该如何解决。

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

    ...
}

当我这样做时

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

我会遇到以下错误:

'MainMenuOption'的'QObject'是一个模糊的基类

我让NavigatableItem从QObject继承是因为信号。有没有办法解决这个问题?

编辑:

在每个继承声明中添加virtual关键字,仍然会给出相同的错误:

class NavigatableItem : public virtual QObject

class Button : public virtual NavigatableItem, public virtual QToolButton

class MainMenuOption : public virtual Button

即使进行了“清除所有”、“运行qmake”和“构建所有”操作后,仍然存在问题。

5
你不能从多个QObject子类继承,只能有一个子类是QObject,而且它必须是列表中的第一个。 - Frank Osterfeld
1
尝试删除那些 moc_**.obj 文件,并进行整体重建。 - liaK
重建没有解决它。 - RvdK
3个回答

8
需要更多的代码,但是我过去所做的是将它们中的一个(在这种情况下是您的NavigatableItem)制作为纯虚类,即接口。不使用“signals”宏,而是使它们成为纯虚保护函数。然后从您的QObject派生类以及接口进行多重继承,并实现这些方法。
我知道这有点争议性,但是尽可能避免多重实现继承确实解决了许多问题和混乱。Google C++ Style Guidelines建议这样做,我认为这是很好的建议。
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();
        ...
}

谢谢Dave,这是我同时所做的,至少我能够构建项目。然而一个副作用是,如果我有一个需要成为NavigatableItem的textentry对象,我必须重新定义每个deselected/selected和activated信号。 - RvdK
2
你需要重新定义它们,但不应该重新实现它们。通常有一种方法可以将它们放在某个公共类中(可能只是一个实用程序类),将其作为您继承类的私有成员包含进去,并使您的继承类具有“拥有”关系而不是“是”关系。是的,这会增加一些额外的代码,但您的实际业务逻辑通常可以保持在一个地方,以避免“复制和粘贴”错误。我发现这样做值得避免多重继承带来的其他问题,但我承认这只是一种观点。 - Dave Mateer

0

0
使用虚拟继承,例如:
class X : public virtual Y 
{
};

class Z : public virtual Y
{
};

class A : public virtual X, public virtual Z
{
};

将只有一个基类 Y 的副本


我在所有继承声明中添加了虚拟关键字,但它仍然给我相同的错误。 - RvdK
1
尝试通过运行以下命令重新生成 MOC 文件:make distclean; qmake; make。 - Tobias
添加虚拟环境并重新构建没有解决问题。 - RvdK
3
由于无法使QToolButton虚继承QObject,在这种情况下它将无法工作。 - Jan Hudec
1
在声明“类A”时,不应该有任何virtual。只有Y必须以虚拟方式继承,这正是PoweRoy 无法做到的。 - Jan Hudec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接