这是我的代码的简化版本:
#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] 删除。
我来说两句