Qt信号/槽:从临时对象发出信号是错误的吗?

Qt signals/slots: Is it an error to emit a signal from a temporary object?

本文关键字:信号 错误 临时对象 Qt      更新时间:2023-10-16

在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
}

可以看到,临时对象从其构造函数发出信号,然后立即销毁。因此,可以在发送信号的对象被销毁后调用该槽位

这是安全的,还是一个潜在的问题或错误条件?

您所指定的将是从信号到插槽的直接连接。这意味着在你发出handySignal的那一刻,它应该去执行所有连接的插槽。一旦所有的槽(即。handySlot)已经返回,那么发射器将返回并完成构造函数。

如果你要指定一个排队连接,如果它是从一个线程中的信号到另一个线程中的插槽的连接,那么请求将被放入事件循环中执行。

所以我会说:是的,如果你没有传递无效的引用,那么从临时对象发出信号似乎很好。

这个例子似乎有点武断,因为我真的没有看到在构造函数中与信号建立连接的意义,然后发出信号,仅此而已。您不妨直接调用该插槽,除非您希望在另一个线程中创建对象,而您没有提到。

编辑:

根据@Kamil的评论,应该注意的是,如果未指定连接类型,则默认为AutoConnection,这意味着实际类型将由目标插槽是否在与发送方不同的线程中确定。如果没有线程,它将等同于DirectConnection。如果使用线程,它将最终成为QueuedConnection。

我会说从临时对象发出是安全的,因为QObject::destroyed "在对象obj被销毁之前立即发出" -Qt docs

所以从临时对象发出的信号应该是安全的,合适的。