C++ 中 QObject 多重继承和策略/特征设计的问题

Posted

技术标签:

【中文标题】C++ 中 QObject 多重继承和策略/特征设计的问题【英文标题】:Problems with QObject multiple inheritance and policy/traits design in C++ 【发布时间】:2011-07-27 11:01:25 【问题描述】:

我在业余时间构建了一个相当大的插件驱动应用程序,并且遇到了一个显示停止设计缺陷。我的应用程序使用基于策略/特征的设计,但因为我使用 Qt,所以它只是通过 MI(而不是模板和 MI)来完成。其中一些类是纯虚拟的,而另一些则在底层执行最终用户不应接触的相当关键的功能。

我的问题是其中一些类需要信号/插槽,因此从 QObject 派生,没问题我可以虚拟地从它继承。但是,我遇到的问题是,我想从 Qt 类派生,然后用我的一个或多个特征对其进行扩展,例如:

class Sy_abstractGLViewport : public QGLWidget, public Sy_saveable, public Sy_abstractObject

    ...

这里QGLWidget是从QObject派生的,但不是虚拟的,会造成歧义问题。

我考虑了一种桥接模式,例如,我将Sy_saveable 设为纯虚拟,然后从中派生一个包含实际实现的Sy_saveable_imp。然后通过聚合将其用于我的Sy_abstractGLViewport

这对我来说似乎相当不专业,因为该应用程序是基于插件的,对于我未来的插件编写者来说,将所有接口方法“连接”到聚合实例有点像 PITA。我什至不能通过宏来自动化它,因为最终用户可能想要覆盖一个方法。

有没有人解决这个问题的模式?或者不需要 MI 但给我同样的灵活性的模式?这是我个人的爱好项目,我不介意进行大量重构 - 我想做正确

【问题讨论】:

不确定你是否这样做,但我实际上不会从 QObject 继承。它适用于 qt 4.7 及之前版本,但可能不适用于 qt 4.8。见bugreports.qt.nokia.com/browse/QTBUG-19717 【参考方案1】:

您不能从继承 QObject 的多个类继承。

尝试使用组合而不是继承。见composition over inheritance。

您也可以尝试使用Q3Signal 类。虽然根据 QT doc 它属于旧 QT3:

Q3Signal 类可用于为不支持的类发送信号 继承 QObject。

【讨论】:

只要在父类中声明为虚拟继承,就可以从 QObject 多次继承——但 Qt 自己的类没有。组合的问题在于,它允许用户从本质上覆盖不应该的方法(因为我依靠它们来正确构建访问器方法),或者根本不构建相关的访问器。 不,您不应该对 QObjects 使用虚拟继承 (doc.qt.nokia.com/latest/…)。不要这样做,即使你的代码编译了,你也会遇到奇怪的行为。 好吧,因为我很懒,所以不喜欢作曲,我不得不承认这是我唯一的出路。我设法保留了我的 is_a 关系,方法是让我的旧特征类接口,然后从中创建最终用户为其聚合成员派生的“实现”类。

以上是关于C++ 中 QObject 多重继承和策略/特征设计的问题的主要内容,如果未能解决你的问题,请参考以下文章

QObject的多重继承

使用 qobject 基础的多重继承

如果 QObject 是从 DIRECTLY 派生的,那么使用 *virtual* 多重继承是不是安全?

为啥在多重继承的情况下QObject需要是第一个

在 C++ QObject 子类中调用析构函数之前执行操作

Qt中图元对象的多重集成