Qt / Windows:在全局范围对象的构造函数中连接信号和插槽时崩溃

Posted

技术标签:

【中文标题】Qt / Windows:在全局范围对象的构造函数中连接信号和插槽时崩溃【英文标题】:Qt / Windows: crash when connecting a signal and slot in the constructor of a globally scoped object 【发布时间】:2020-04-22 19:42:51 【问题描述】:

当我在 Windows 上的 Qt Creator 中编译和运行以下程序时会崩溃:

TestObject.h:

#include <QObject>

class TestObject : public QObject 
    Q_OBJECT
public:
    TestObject(QObject *parent = nullptr);
signals:
    void signal();
public slots:
    void slot();
;

TestObject.cpp:

#include "TestObject.h"

TestObject::TestObject(QObject *parent) : QObject(parent) 
    connect(this, &TestObject::signal, this, &TestObject::slot);


void TestObject::slot() 

TestObject global;

int main(int argc, char *argv[]) 
    TestObject local;
    return 0;

如果我在 TestObject 的构造函数或 TestObject globalVar; 中删除对 connect 的调用,则不会发生崩溃。在全局范围的构造函数中调用 connect 的某些事情出错了。 main() 中的局部范围变量不会导致任何问题。

我尝试过针对 Qt 5.9.9、5.11.2 和 5.14.2 进行编译,但它们都有相同的崩溃。

如果我在 macOS 上编译相同的程序,就不会崩溃。

我做错了什么,或者有什么方法可以解决这个问题?

【问题讨论】:

【参考方案1】:

来自documentation...

一般来说,不支持在 QApplication 之前创建 QObject 并且可能导致退出时出现奇怪的崩溃,具体取决于平台。这 表示也不支持 QObject 的静态实例。一个适当的 结构化的单线程或多线程应用程序应该使 QApplication 是第一个创建的,最后一个销毁的 QObject。

所以目前不支持你所拥有的。

【讨论】:

以上是关于Qt / Windows:在全局范围对象的构造函数中连接信号和插槽时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

静态函数范围对象的构造是线程安全的吗?

QT/C++构造函数参数简单问题

你如何优先考虑全局构造函数?

静态对象和全局对象的销毁顺序是啥?

在构造函数之外延长 QT 对象的生命周期

首先调用的是 DllMain() 还是全局静态对象构造函数?