I wrote the following code, which doesn't provoke any error:
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;
};
However, Qt documentation for QMainWindow::setCentralWidget says that
Note: QMainWindow takes ownership of the widget pointer and deletes it at the appropriate time.
Shouldn't there be a crash on finishing app because of double deleting of view: by Qt's ownership model and by ~MainWindow()?
This would work as written. The behavior is well defined.
The way Qt ownership works, every
QObject-derived object keeps a list of the children it owns, as well as a pointer to its parent it is owned by.QObjectdestructor then does two things - it destroys all children, and also notifies its parent that it has been destroyed. In response to that, the parent removes this now-destroyed child from its list of owned objects.In your example, when
MainWindowobject is constructed, the base classQObjectconstructor runs first, (then other base class constructos), and then constructors of data members, includingview. The destruction proceeds in the reverse order:viewis destroyed first, whereupon it notifies its ownerMainWindowobject (or rather, theQObjectbase class sub-object withinMainWindow) to remove itself from the list. Then eventuallyQObjectdestructor runs, but by that time a pointer toviewis no longer in the list.By this mechanism, double deletion is avoided.