Qt 为什么不';QoObject删除两次,如果它们同时是类成员和子对象?

Qt 为什么不';QoObject删除两次,如果它们同时是类成员和子对象?,qt,memory-management,memory-leaks,Qt,Memory Management,Memory Leaks,如果QObject是类的成员(不是使用新运算符创建的),同时也是类实例的子对象,则应将其删除两次,因为类实例的所有子对象都将被删除,并且在类的Destructor中,所有类成员都将被删除。因此,程序应该崩溃。但这并没有发生,所以Qt必须检测到这种双重关系。但这真的发生了吗?如果是,它是如何工作的 以下是一个例子: class MyWindow : public QMainWindow { Q_OBJECT public: MyWindow(); QLabel label; };

如果QObject是类的成员(不是使用新运算符创建的),同时也是类实例的子对象,则应将其删除两次,因为类实例的所有子对象都将被删除,并且在类的Destructor中,所有类成员都将被删除。因此,程序应该崩溃。但这并没有发生,所以Qt必须检测到这种双重关系。但这真的发生了吗?如果是,它是如何工作的

以下是一个例子:

class MyWindow : public QMainWindow {
Q_OBJECT
public:
    MyWindow();
    QLabel label;
};

MyWindow::MyWindow() : label(this) {}

MyWindow
的实例被销毁时,
label
应该被删除两次,因为它是
MyWindow
的成员和子级。但这并没有发生,而且这样做似乎是安全的。但是它是如何工作的呢?

根据Qt文档:
你也可以自己删除子对象,它们将从父对象中删除自己。
我认为这意味着子对象作为其析构函数的一部分负责分离。从


也可以注意到,C++中的销毁顺序指定成员析构函数在基类析构函数之前调用,参见。因此,标签将在MyWindow需要删除它之前删除自身。

在这种情况下,由于删除顺序的原因,此操作有效:

  • 首先调用~MyWindow(),这会破坏标签。标签的~QObject()析构函数从父对象的子对象列表中删除该对象
  • 在~MyWindow()之后,在某个点调用MyWindow的~QObject()析构函数,该析构函数删除窗口的子项。但是,由于标签指针已从子项列表中删除,因此不会再次尝试删除标签