在这里,我的信号声明:
signals:
void mySignal(MyClass *);
我是如何使用它的:
MyClass *myObject=new myClass();
emit mySignal(myObject);
我的问题出现了:谁负责删除myObject:
发件人代码,如果在使用myObject之前删除了什么?悬空指针
连接到信号的插槽,如果没有插槽或连接到信号的多个插槽怎么办?内存泄漏或悬空指针
Qt如何在其内置信号中管理这种情况?它是否使用内部引用计数?
您的最佳做法是什么?
答案 0 :(得分:10)
您可以根据需要连接多个插槽的信号,因此您应该确保这些插槽中没有一个能够执行您不希望他们对您的对象执行的操作:
const
引用,那么根据您的连接类型,QT会为您传递对象的值(有关详细信息,请参阅this)有关在信号中传递指针的一些想法,请参阅此question。
答案 1 :(得分:5)
关于第一个问题,请使用QPointer
关于第二个问题,
如果我清楚地理解,即使您发送myObject
,仍会在您发出信号的班级中有参考 myObject
。那怎么会是内存泄漏还是悬空指针?你仍然可以访问来自发布的类的myObject
,不是吗?
希望很清楚..
编辑:
从您的评论中我相信您正在发布/删除插槽中的对象。现在我假设你的问题是,如果(内存释放)插槽被调用一次,两次或根本没有被调用,该怎么办。
您可以使用QPointer。从Qt文档中,
当您需要存储指向其他人拥有的QPointer
的指针时,有保护的指针(QObject
)非常有用,因此当您仍然保留对其的引用时可能会将其销毁它。您可以安全地测试指针的有效性。
Qt文档本身的一个例子,
QPointer<QLabel> label = new QLabel;
label->setText("&Status:");
...
if (label)
label->show();
解释继续这样......
如果在此期间删除QLabel,则标签变量将保留0而不是无效地址,并且最后一行将永远不会被执行。此处QLabel将是您的MyClass
和标签是你的myObject
。在使用之前,请检查 Nullity 。
答案 2 :(得分:3)
在1):发件人应该小心。当同步发送信号(而不是排队)时,当接收器接收到该对象时,该对象仍然存活。如果接收者需要存储它,只有QPointer会有所帮助,但是MyClass需要从QObject派生,这从上下文看起来是错误的。 无论如何,这是一般的终身问题,而不是信号/插槽特定的。
替代方案:使用值类并通过const引用发送它。如果MyClass可以有子类,则传递const QSharedPointer&amp;
关于deleteLater:deleteLater()在这里没有帮助。它会使排队的连接更安全,对于直接连接,它没有任何区别。 deleteLater()发挥作用的一个用途是接收者是否需要删除发送者。然后应该总是使用deleteLater(),这样发送者就可以完成他正在做的事情,否则会崩溃。
答案 3 :(得分:0)
总之(好吧,函数名) - deleteLater():)所有QObject都有它。它将标记要删除的对象,然后在下一个事件循环更新时发生。