繁体   English   中英

为什么QObject会破坏被破坏的信号?

[英]Why is QObject destroyed signal called AFTER the destruction?

考虑这个测试用例:

class MyObject : public QObject
{
    Q_OBJECT
public:
    MyObject() { qDebug() << "MyObject constructor"; }
    virtual ~MyObject() { qDebug() << "MyObject destructor"; }
};

class Tracker : public QObject
{
    Q_OBJECT
public:
    Tracker() {}

public slots:
    void onDestructor() { qDebug() << "About to be destroyed!"; }
};

int main(int argc, char** argv)
{
    QCoreApplication app(argc, argv);

    Tracker tracker;

    MyObject *obj = new MyObject();
    QObject::connect(obj, SIGNAL(destroyed()), &tracker, SLOT(onDestructor()));
    delete obj;

    return app.exec();
}

它打印这个:

MyObject constructor
MyObject destructor
About to be destroyed!

这种行为与Qt文档相矛盾: “此信号在对象obj被销毁之前立即发出,并且无法阻止。” 为什么会这样?

如果你考虑信号将如何发射,它是由基础QObject完成的 - 这就是QObject知道它被破坏的方式。

因此,当派生类被销毁时,最派生的析构函数首先运行(按照标准C ++ dtor处理),并显示"MyObject destructor"消息。 当dtor完成时,基本的dtors会运行,在这种情况下,它就是QObject dtor,然后发出信号和"About to be destroyed!" 消息显示。

您提到的文档中的措辞可能有点不精确。 它的措辞可能更好,例如“当对象obj被破坏时发出此信号”或“在对象obj完全被破坏之前立即发出此信号”。

迈克尔的答案是正确的,只要使用直接连接。

如果使用排队连接,则在主事件循环的下一次迭代中调用插槽。 将其与发出信号的对象的析构函数相结合,很明显为什么结果与直接连接相同。

另见官方文档:

请注意,连接类型可能会对线程编程产生影响。 (短版本:Direct在与信号相同的线程中执行槽,但排队在接收器线程中运行)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM