为什么根据我创建应用程序实例的方式,Qt5 会出现奇怪的崩溃?

阿拉斯泰尔

这是我的代码的简化版本:

#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>


class MainView : public QMainWindow
{
    public:
        static MainView *Initialise(int argc, char **argv);

        int Run() { return qApp->exec(); }

    private:
        MainView() { }
        virtual ~MainView() { }

};


namespace
{
    QApplication *s_app      {nullptr};
    MainView     *s_instance {nullptr};
};


MainView *MainView::Initialise(int argc, char **argv)
{
    if (nullptr == s_app) {
        s_app = new QApplication(argc, argv);
    }

    if (nullptr == s_instance) {
        s_instance = dynamic_cast<MainView *>(new MainView());
    }

    return s_instance;
}


class Framework
{
    public:
        Framework() { }
        ~Framework() { }

        int Initialise(int argc, char **argv)
        {
            m_main_view = MainView::Initialise(argc, argv);

            return 0;
        }

        int Run()
        {
            m_main_view->show();
            return m_main_view->Run();
        }

    private:
        MainView *m_main_view;

};


int main(int argc, char **argv)
{
    Framework  framework;
    int        result = 0;

    // Weirdness here!!!!
    MainView::Initialise(argc, argv);  // Crashes even with this line.

    result = framework.Initialise(argc, argv);
    if (0 == result) {
        result = framework.Run();
    }

    return result;
}

此代码在显示 MainWindow 实例时崩溃。在此代码的完整版本中,MainView 继承自虚拟接口类(以便我可以解耦视图并替换命令行接口或测试接口),除非我注释掉标记为的代码,否则它不会崩溃“这里很奇怪”。

在这段代码中,如果我替换:

MainView::Initialise(argc, argv);  // Crashes even with this line.

与:

if (nullptr == s_app) {
    s_app = new QApplication(argc, argv);
}

然后它工作正常并且不会崩溃。

从本质上讲,如果应用程序中实例化的MainView::Initialise(),无论是从所谓的main()Framework::Initialise()然后程序崩溃,但如果我在初始化应用main()第一,然后它不会崩溃。

main()如果可能的话,我不希望我的函数对 UI 有任何了解,即使考虑到我的虚拟基类接口。应该没有必要,它使main()不必要的混乱。

那么为什么会崩溃,我该如何阻止它?

拉克斯

调用 in中的QApplication构造函数main()和调用 in之间存在细微差别MainView::Initialise()

QApplication 构造函数的文档说:

QApplication:: QApplication ( int &argc, char **argv)

< ... >

注意: argc 和 argv 可能会随着 Qt 删除它识别的命令行参数而改变。

因此,在调用 in 中的构造函数时MainView::Initialise(),您实际上是在传递argc来自 main 的的副本据推测,Qt 在内部某处存储了对 this 的引用,当 QApplication 稍后在构建窗口期间取消引用它时,会导致它崩溃。

如果您更改两个Initialise()函数的签名以引用 argc,则程序可以正常运行而不会崩溃。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

解除实例分配期间,ARC不会出现奇怪的行为

为什么在OS X的PowerPoint中会出现这个奇怪的字符?

为什么在PostgreSQL中使用SETOF会出现这种奇怪的行为?

为什么我的应用程序崩溃了?

为什么在部署我的 Angular 9 + Firebase 应用程序后会出现路由错误

为什么Android会强制停止我的应用程序而不会出现任何错误?

为什么在我的 web 应用程序中使用 Tomcat 会出现 Class NotFound 异常?

为什么在StackBlitz上运行时,我的Angular应用程序会出现错误?

为什么会出现“应用程序不带参数”的提示,我该如何解决?

为什么我的 React 应用程序会出现此错误?

运行Qt5应用程序时出现Qt错误消息

在处理完所有所有内容后,为什么会出现错误和崩溃代码0?

为什么我的按钮使我的应用程序崩溃?

使用应用程序发生奇怪的崩溃

在 Heroku 上运行我的应用程序时,为什么会出现引导超时错误(错误 R10)?

为什么在我的 Flutter 应用程序中打开新页面时会出现此错误?

当我使用flask cli运行我的应用程序时,为什么会出现错误“未从...获得有效的Flask应用程序”?

从我的 Android 应用程序收到奇怪/可疑的崩溃报告

为什么会出现NoSuchMethodException?

为什么会出现NullPointerException?

为什么会出现KeyError?

为什么会出现“?”字符?

为什么会出现RemoteCertificateNameMismatch?

为什么会出现僵局?

为什么会出现nullpointerexception?

为什么会出现IndexError?

为什么会出现NameError?

为什么会出现溢出?

为什么会出现CancelledKeyException?