【问题标题】:Qt multiple inheritance and signalsQt 多重继承和信号
【发布时间】:2011-03-23 10:27:38
【问题描述】:

由于 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

    ...
}

当我这样做时

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

我会得到错误:

QObject' 是 'MainMenuOption' 的模棱两可的基础

我之所以让 NavigatableItem 从 QObject 继承是因为信号。有没有办法做到这一点?

编辑:

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

class NavigatableItem : public virtual QObject

class Button : public virtual NavigatableItem, public virtual QToolButton

class MainMenuOption : public virtual Button

即使在“clean all”、“run qmake”和“build all”之后。

【问题讨论】:

  • 你不能从多个 QObject 子类继承。 QObject只能是其中一个,并且必须是列表中的第一个。
  • 尝试删除那些moc_*,*.obj 文件并重新构建所有文件..
  • 查看更新的问题。重建并没有解决它。

标签: c++ qt multiple-inheritance qt-signals


【解决方案1】:

它需要更多代码,但我过去所做的是将其中一个(在本例中为您的NavigatableItem)制作为纯虚拟类,即接口。不要使用“信号”宏,而是让它们成为纯虚拟保护函数。然后从您的 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 对象,我必须重新定义每个取消选择/选择和激活的信号。
  • 您必须重新定义它们,但不必重新实现它们。通常有一种方法可以将它们放在某个公共类(可能只是一个实用程序类)中,将其作为继承类的私有成员包含在内,并使您的继承类具有“has-a”关系而不是“is” -a' 关系。是的,这是一些额外的代码,但是您的实际业务逻辑通常可以保存在一个地方,这样您就可以避免“复制和粘贴”错误。我发现避免多重继承的其他问题是值得的,但我很乐意承认这只是一种观点。
【解决方案2】:

使用虚拟继承,例如

class X : public virtual Y 
{
};

class Z : public virtual Y
{
};

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

将只有一个基类 Y 的副本

【讨论】:

  • 我在所有继承声明中添加了 virtual,但它仍然给了我同样的错误。
  • 尝试通过运行重新生成 MOC 文件: make distclean; qmake;制作。
  • 查看更新的问题。添加虚拟和重建并没有解决它。
  • @PoweRoy:因为你不能让QToolButton虚拟继承QObject,所以在这种情况下是行不通的。
  • class A 的声明中不应有任何virtual。只有 Y 必须虚拟继承,而这正是 PoweRoy不能 做的。
【解决方案3】:

你应该使用虚拟继承。

http://en.allexperts.com/q/C-1040/virtual-inheritance.htm

您似乎遇到了钻石问题,另请参阅:

http://www.cprogramming.com/tutorial/virtual_inheritance.html

这样做:

class NavigatableItem : public virtual QObject
class Button : public virtual NavigatableItem, public virtual QToolButton
class MainMenuOption : public Button

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-14
    • 2015-01-18
    • 1970-01-01
    相关资源
    最近更新 更多