我编写了以下代码,它不会引发任何错误:
main.cpp
#include "main_window.hpp"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
main_window.hpp
#pragma once
#include "ui_main_window.h"
#include <QtWidgets/QMainWindow>
#include <QGraphicsView>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
setCentralWidget(&view);
}
private:
Ui::MainWindowClass ui;
QGraphicsView view;
};
但是,
QMainWindow::setCentralWidget
的 Qt 文档说
注意:QMainWindow 获得小部件指针的所有权并在适当的时间将其删除。
由于 Qt 所有权模型和
view
的双重删除 ~MainWindow()
,完成应用程序时不应该发生崩溃吗?
这将按所写的那样工作。行为已明确定义。
Qt 所有权的工作方式是,每个
QObject
派生的对象都保留它所拥有的子对象的列表,以及指向它所拥有的父对象的指针。然后,QObject
析构函数会做两件事 - 它销毁所有子级,并通知其父级它已被销毁。作为回应,父级将这个现已被销毁的子级从其拥有的对象列表中删除。
在您的示例中,当构造
MainWindow
对象时,首先运行基类 QObject
构造函数(然后是其他基类构造函数),然后是数据成员的构造函数,包括 view
。销毁按相反的顺序进行:首先销毁 view
,然后通知其所有者 MainWindow
对象(或者更确切地说,QObject
中的 MainWindow
基类子对象)将其自身从列表中删除。然后最终 QObject
析构函数运行,但那时指向 view
的指针不再在列表中。
通过这种机制,避免了双重删除。