在Qt中,如果从临时对象调用信号,这样在调用插槽时可能会删除该对象,这是一个错误吗?
如果相关,则代码从临时对象的构造函数发出信号。
(注意:没有指针或引用作为参数传递,所以这不是关于悬空指针或引用的问题。我只想知道,以最简单的形式,是否可以发出信号来自Qt中的临时对象。)
以下是我的代码的缩短版本:
// My application
class HandyApplication: public QApplication
{
Q_OBJECT
public:
explicit HandyApplication( int argc, char * argv[] );
signals:
public slots:
void handySlot(std::string const msg);
};
// Class that will be instantiated to a temporary object
class Handy: public QObject
{
Q_OBJECT
public:
Handy()
{
QObject::connect(this, SIGNAL(handySignal(std::string const)),
QCoreApplication::instance(),
SLOT(handySlot(std::string const)));
emit handySignal("My Message");
}
signals:
void handySignal(std::string const msg);
};
// An unrelated function that may be called in another thread
void myFunction()
{
Handy temporaryObject; // This constructor call will emit the signal "handySignal" above
}
如您所见,临时对象从其构造函数发出信号,然后立即销毁。 因此,可以在发送信号的对象被销毁后调用插槽。
这是安全的,还是潜在的问题或错误情况?
答案 0 :(得分:4)
您指定的内容是从信号到插槽的direct connection。这意味着,当您发出handySignal
时,它应该执行所有连接的插槽。一旦所有的槽(即handySlot
)都返回,那么发射器将返回并完成构造函数。
如果要指定queued connection,如果它是从一个线程中的信号到另一个线程中的一个插槽的连接,那么请求将被放入事件循环中执行。
所以我会说:是的,从临时对象发出信号似乎很好,如果你没有传递无效的引用。
这个例子似乎有点随意,因为我没有真正看到在构造函数中建立一个信号的点,然后你发出一个信号,就是这样。你也可以只调用那个插槽,除非你期望在另一个线程中创建对象,你没有提到。
编辑:
根据@Kamil的评论,应该注意的是,如果未指定连接类型,则defailt为AutoConnection,这意味着实际类型将由目标槽是否在不同的线程中确定比发件人。没有线程,它将等同于DirectConnection。使用线程,它最终会成为QueuedConnection。
答案 1 :(得分:1)
我想说从临时对象发出是安全的,因为QObject::destroyed
"是在对象obj被销毁之前立即发出的#34; - Qt docs
因此,假设从临时物体发出的信号是安全和正确的。