class MyMainWindow : public QMainWindow
{
private:
SomeDependency someDependency;
}
class SomeWidget : public QWidget
{
public:
~SomeWidget()
{
// Use someDependency by getting it from MyMainWindow (or having MyMainWindow pass it in)
}
}
MyMainWindow::MyMainWindow(QWidget* parent)
: QMainWindow(parent)
{
SomeWidget* someWidget = new SomeWidget(this);
}
我遇到这种模式的问题。
MyMainWindow
拥有SomeDependency
。 MyMainWindow
在堆上创建一个新的SomeWidget
,并为其提供父级this
。SomeWidget
的析构函数需要调用SomeDependency
来执行某项操作(例如,在死时将其自身从依赖项中注销)。当小部件正常消失时,此方法工作正常。但是,当该应用程序被杀死时,就会出现一个奇怪的问题。首先调用
MyMainWindow
析构函数。它将清除SomeDependency
。接下来,调用QMainWindow
析构函数。这将清理其所有子级。它开始删除其子级,从而导致SomeWidget
被销毁。 SomeWidget::~SomeWidget()
然后调用SomeDependency
...,但是它已被销毁,因此应用程序崩溃了。我该如何按照Qt父/子内存生存期规则进行操作,但让子级从
MyMainWindow
获取依赖项? 最佳答案
最简单的解决方案是做您一直应该做的事情:不要在堆上分配子窗口小部件,除非需要动态创建它们。 C ++具有明确定义的语义:m_widget
将在m_dependency
之前销毁。
class MyMainWindow : public QMainWindow
{
SomeDependency m_dependency;
SomeWidget m_widget;
};
对于
m_widget
来说,最好将MyMainWindow
作为父级。或者,如果出于某种原因需要动态创建小部件,请执行以下操作:
class MyMainWindow : public QMainWindow
{
SomeDependency m_dependency;
QScopedPointer<SomeWidget> m_widget;
};
最后,
SomeWidget
可以共享SomeDependency
的所有权:class MyMainWindow : public QMainWindow
{
QSharedPointer<SomeDependency> m_dependency;
QScopedPointer<SomeWidget> m_widget { m_dependency };
};
class SomeWidget : public QWidget {
QSharedPointer<SomeDependency> m_dependency;
public:
SomeWidget(QScopedPointer<SomeDependency> dep, QWidget * parent = 0) :
m_dependency(dep) {
...
}
};
旁注:确保您确实需要
QMainWindow
。如果QDialog
可以使用,请不要使用它。关于c++ - 子级小部件依赖于父级的依赖项时崩溃,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35299718/