我有一个“普通”(非qt派生)类。它正在传递一个QObject引用。在此类中,我想将输入的QObject信号与lambda连接。 到目前为止,一切正常,除非在传递给QObject之前销毁了我的类的对象。现在,来自QObject的信号指向的lambda不再存在。
通常的做法是,我的类继承自QObject,并将this
作为上下文传递给connect
。我的对象死亡后,连接将被Qt代码自动破坏。
解决此问题的另一种方法是保存connect的返回结果,即QMetaObject::Connection
,然后保存在我的类调用QObject::disconnect(resultOfConnect)
的析构函数中。
现在我想解决的方式是这样的:
class SomeQtDerivedClass : public QObject {...}
class MyClass
{
public:
MyClass(SomeQtDerivedClass& qtObject)
{
connect(&qtObject, &qtObject::someSignal, &m_QtObject, [](){blahblah})
}
private:
QObject m_QtObject;
}
我没有在任何地方使用过这种模式,而且在官方文档中也找不到关于这种方法的任何东西。如果可以改用合成,我不想从QObject继承。如果可以在堆栈上创建m_QtObject,我不想在其上创建。而且,如果我的类对象在输入的QObject之前被销毁,我希望自动销毁连接。
这项工作可以吗?
答案 0 :(得分:4)
它应该可以正常工作(当然,只要您没有在m_QtObject
上设置父对象); m_QtObject
与您的类一起被销毁(在用户提供的析构函数之后,如果有的话),因此它与您从QObject
派生的几乎没有什么不同(实际上,从许多角度来看,基类都非常相似)给隐藏的头等舱成员)。
话虽这么说,我会使用QMetaObject::Connection
(可能将其包装到std::unique_ptr
中,或在破坏时自动断开连接); QObject
的重量很重,仅使用它来利用其自动断开连接功能似乎有点浪费。
答案 1 :(得分:2)
这不是问题的直接答案,但它回答了@vuko_zrno的误解。
拥有QObject
作为成员(反对QObject *
)不能保证您进行堆栈分配。它仅向您保证QObject将使用与拥有它的MyClass
实例相同的内存块。
例如,如果您执行MyClass obj;
,则MyClass和QObject都将在堆栈上。但是如果您执行MyClass * obj = new MyClass;
,它们都将处于堆中。
Qt类也很重要,它大量使用了pimpl设计模式。这意味着QObject
类只是一个空壳,其所有成员变量都存储在另一个名为QObjectPrivate
的类中。
实际上,QObject
的大小在64位上为16个字节,而QObjectPrivate
的大小为112个字节。并且QObjectPrivate
将始终分配在堆上。
因此在实践中,我不确定QObject
与QObject *
会有什么有意义的区别。