C++ Qt信号/插槽:从临时对象发出信号是错误的吗?
在Qt中,如果从临时对象调用信号,使得在调用时隙时该对象可能被删除,这是错误吗 如果相关,代码将从临时对象的构造函数发出信号 (注意:没有指针或引用作为参数传递,因此这不是关于悬空指针或引用的问题。我只想知道,以最简单的形式,从Qt中的临时对象发出信号是否可以接受。) 以下是我的代码的简化版本:C++ Qt信号/插槽:从临时对象发出信号是错误的吗?,c++,qt,signals-slots,C++,Qt,Signals Slots,在Qt中,如果从临时对象调用信号,使得在调用时隙时该对象可能被删除,这是错误吗 如果相关,代码将从临时对象的构造函数发出信号 (注意:没有指针或引用作为参数传递,因此这不是关于悬空指针或引用的问题。我只想知道,以最简单的形式,从Qt中的临时对象发出信号是否可以接受。) 以下是我的代码的简化版本: // My application class HandyApplication: public QApplication { Q_OBJECT public: expl
// 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
}
如您所见,临时对象从其构造函数发出信号,然后立即被销毁因此,发送信号的对象被销毁后,可以调用插槽
这是安全的,还是潜在的问题或错误情况?您指定的是从信号到插槽的连接。这意味着在您发出
handySignal
时,它应该去执行所有连接的插槽。一旦所有插槽(即handySlot
)都返回,发射器将返回并与构造函数一起完成
如果要指定从一个线程中的信号到另一个线程中的插槽的连接,则会使用该连接,然后将请求放入要执行的事件循环中
所以我想说:是的,从一个临时对象发出一个信号似乎很好,如果你不传递无效的引用
这个例子似乎有点武断,因为我真的看不出在构造函数中建立一个到信号的连接有什么意义,然后你就会发出信号,就这样。您也可以调用该插槽,除非您希望在不同的线程中创建对象,而您没有提到
编辑:
根据@Kamil的评论,应该注意的是,如果未指定连接类型,则具有的defilt将是自动连接,这意味着实际类型将由目标插槽是否位于与发送方不同的线程中来确定。如果没有线程,它将等同于DirectConnection。使用线程,它最终将成为一个队列连接。我认为从临时对象发出是安全的,因为
QObject::destrocted
“在对象对象被销毁之前立即发出”-
因此,假设从临时对象发出的信号是安全的和正确的。如果信号是从调用插槽的线程以外的其他线程发出的,那么发出的调用可能是异步的,这不是真的吗?@DanNissenbaum:Ya我是这么说的。当它位于不同的线程中时,它将成为排队连接。但即使是这样,如果信号没有发射出可能无效的物体,那么就没有真正的问题。该调用被注册到目标线程事件循环中并被调用,而不管发送方是谁。您需要该调用是同步的还是异步的,还是不在乎?在前一种情况下,您不妨调用该方法(
obj->method(args)
);在后者中,使用QMetaObject::invokeMethod
和QueuedConnection
强制调用在返回事件循环时发生。@jdi-我们需要澄清一件事。默认情况下,将使用Qt::AutoConnection,因此当创建的对象位于不同的线程中时,它的行为会有所不同。@KamilKlimek:是的,我的回答可能不清楚。我试图提出这样的建议,只是因为OPs代码没有显示线程的迹象,这相当于直接连接。