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

Posted

技术标签:

【中文标题】如果 QObject 是从 DIRECTLY 派生的,那么使用 *virtual* 多重继承是不是安全?【英文标题】:Is it safe to use *virtual* multiple inheritance if QObject is being derived from DIRECTLY?如果 QObject 是从 DIRECTLY 派生的,那么使用 *virtual* 多重继承是否安全? 【发布时间】:2013-05-08 16:40:32 【问题描述】:

我了解,Qt 通常不支持来自QObject 派生类的多重继承(甚至是虚拟多重继承)。

我理解的原因是(我认为)即使在虚拟继承的情况下,Qt 类自身也不会虚拟地从QObject 继承。例如,如果您尝试从 QWidgetQThread 虚拟派生一个类,这会将虚拟继承置于继承链中一个不相关的位置,您仍然会得到两个 QObject 实例。

因此,我认为使用虚拟继承是安全的,并且在 Qt 中得到支持,其中唯一的 Qt 类派生自 QObject 本身。

我有:

class Top : public QObject ;

class Left : public virtual Top ;

class Right : public virtual Top ;

class Bottom : public Left, public Right ; // Is this safe, and supported by Qt?

请注意Bottom 的实例确实只有一个Top 的实例(因此只有一个QObject 的实例),因此在Qt 中避免多重继承的理由似乎是(甚至virtual 多重继承)在这里不适用。

上述构造仍然导致 Qt 编译器警告Class Bottom inherits from two QObject subclasses Left and Right. This is not supported!

我说的对吗?在这种特定情况下忽略 Qt 编译器警告是否安全?上述构造,涉及直接来自 QObject 的虚拟多重继承,在 Qt 中是否安全且受支持?

【问题讨论】:

Qt 是如何实际使用这个类的?如果您只是传递一个指针或对QObject 的引用,那很好。如果它在某处尝试获取成员偏移量,而不是使用指向成员的指针,则可能不是。 @Useless 我希望能够为TopLeftRight 和/或Bottom 绑定Qt 信号和插槽。 好的,所以它是否有效取决于这些实现的细节。我不知道在那种情况下的答案是什么,但至少对于下一个通过 Qt 专家来说是清楚的...... @Dan:您只能为Top 绑定信号和插槽。而Top 可以使用虚函数将实现委托给它的子类,但 Qt 不知道如何处理它们。 【参考方案1】:

不,Qt 不支持来自QObject 的多重继承。

问题不在于虚拟继承,而在于 Qt 的元对象系统。每个QObject 基类都有一个关联的QMetaObject,它管理信号、槽、属性等,每个元对象都知道它的父类QObject,例如可以处理存在于父类中的信号。 Qt moc 无法处理来自QObject 或其任何子类的多重继承。

【讨论】:

确实——即使为Right 类定义signal(大概Left 也是一样的),也会导致compiler 错误跟随moc-生产线:Right *_t = static_cast<Right *>(_o);_oQObject。因此,不仅 Qt 不支持该构造 - 它甚至无法编译。 我想知道 Qt 是否有朝一日支持QObject-派生类的多重继承。

以上是关于如果 QObject 是从 DIRECTLY 派生的,那么使用 *virtual* 多重继承是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章

缺少带有 QObject 的派生类

在 QObject 派生类的构造函数中使用 deleteLater

如何使用 QObject 派生类实例遵循 OOP 基本概念?

如何从基于 QObject 的类方法返回 QList<double> 以在 Qt 脚本中使用

Qt 5:如何制作“纯 C++”客户端套接字?

QML 未能检测到在 C++ 中破坏的 QObject