如果 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
继承。例如,如果您尝试从 QWidget
和 QThread
虚拟派生一个类,这会将虚拟继承置于继承链中一个不相关的位置,您仍然会得到两个 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 我希望能够为Top
、Left
、Right
和/或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);
和_o
和QObject
。因此,不仅 Qt 不支持该构造 - 它甚至无法编译。
我想知道 Qt 是否有朝一日支持QObject
-派生类的多重继承。以上是关于如果 QObject 是从 DIRECTLY 派生的,那么使用 *virtual* 多重继承是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章
在 QObject 派生类的构造函数中使用 deleteLater
如何使用 QObject 派生类实例遵循 OOP 基本概念?