为什么 QObject 销毁后会调用销毁信号?

发布于 2024-12-23 12:59:34 字数 848 浏览 0 评论 0原文

考虑这个测试用例:

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 被销毁之前立即发出此信号,并且无法被阻止。”为什么会出现这种情况?

Consider this test case:

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();
}

It prints this:

MyObject constructor
MyObject destructor
About to be destroyed!

This behaviour contradicts the Qt documentation: "This signal is emitted immediately before the object obj is destroyed, and can not be blocked." Why does this happen?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦里°也失望 2024-12-30 12:59:34

如果您考虑如何发出信号,它是由基础 QObject 完成的 - 这就是 QObject 知道它正在被销毁的方式。

因此,当派生类被销毁时,最派生的析构函数首先运行(根据标准 C++ dtor 处理),并显示 “MyObject destructor” 消息。当该 dtor 完成时,基础 dtor 开始运行,在本例中是 QObject dtor,然后发出信号并显示“即将被销毁!” 消息。

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

If you think about how the signal would get emitted, it's done by the base QObject - that's how the QObject knows it's being destroyed.

So when the derived class is destroyed, the most derived destructor gets run first (per standard C++ dtor handling), and the "MyObject destructor" message is displayed. When that dtor completes, the base dtors get run and in this case that's the QObject dtor, which then emits the signal and the "About to be destroyed!" message is displayed.

The wording in the docs you mentioned might be a bit imprecise. It might be better worded with something like, "This signal is emitted as the object obj is destroyed" or "This signal is emitted immediately before the object obj is completely destroyed".

絕版丫頭 2024-12-30 12:59:34

就使用直接连接而言,迈克尔的答案是正确的。

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

另请参阅官方文档:

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

Michael's answer is correct insofar direct connections are used.

If queued connections are used, the slots are called at the next iteration of the main event loop. Combine that with the destructor of the object emitting the signal, it becomes obvious why the result is the same as for direct connections are involved.

See also the official docs:

Note that Connection type may have consequences for threaded programming. (Short version: Direct executes slot in the same thread as the signal, but queued runs in the receiver thread)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文