Qt 多重继承和信号
Posted
技术标签:
【中文标题】Qt 多重继承和信号【英文标题】:Qt multiple inheritance and signals 【发布时间】: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
文件并重新构建所有文件..
查看更新的问题。重建并没有解决它。
【参考方案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
【讨论】:
以上是关于Qt 多重继承和信号的主要内容,如果未能解决你的问题,请参考以下文章