QObject自动删除顺序

3

我有一份示例代码:

#include <QCoreApplication>
#include <QTimer>
#include <cstdio>

using namespace std;

class A : public QObject
{
public:
  ~A() { printf("destructor A\n"); }
};

class B : public QObject
{
public:
  B(QObject * parent) : QObject(parent) { }
  ~B() { printf("destructor B\n"); }
};

class C : public QObject
{
public:
  C(QObject * parent) : QObject(parent) { }
  ~C() { printf("destructor C\n"); }
};

int main(int argc, char *argv[])
{
  QCoreApplication app(argc, argv);
  auto * a = new A;
  auto * b = new B(a);
  auto * c = new C(a);

  delete a;

  QTimer::singleShot(30000, &app, &QCoreApplication::quit);
  return app.exec();
}

执行以上应用程序会给我以下结果:
destructor A
destructor B
destructor C

auto(qt)销毁操作的顺序是什么?

我可以假设销毁(B, C)的顺序与创建(new B(a), new C(a))的顺序相同吗?

为什么销毁的顺序不是:A,C,B?

2个回答

3
一旦在 a 上调用 delete,它的子元素 bc 也会被删除,删除顺序与它们添加到 a 的子元素集合中的顺序相同。 为了演示这一点,您可以创建没有父级参数的 bc,然后稍后调用 setParent:销毁顺序将是调用的相同顺序。

2
回答你的问题需要两部分信息。首先是添加子项的顺序。从QObject::children()的文档中可以看到:

第一个添加的子项是列表中的第一个对象,最后添加的子项是列表中的最后一个对象,也就是说,新的子项会被追加到末尾。

然后,从QObject析构函数开始,deleteChildren()函数执行以下操作:

for (int i = 0; i < children.count(); ++i) {
    currentChildBeingDeleted = children.at(i);
    children[i] = 0;
    delete currentChildBeingDeleted;
}
children.clear();

所以它按照它们被添加到子列表中的顺序删除它们。
对于每个QObject子类,这都是正确的,除了UI对象,即QWidget及其子类。再次从文档中可以得知:

请注意,当QWidget子项被提升或降低时,列表顺序会更改。被提升的小部件成为列表中的最后一个对象,而被降低的小部件成为列表中的第一个对象。

因此,调用raise()或lower()会操作列表,因此它们被删除的顺序不再那么简单。但对于非UI对象,它们按照它们在构造函数中给定的父级或通过QObject::setParent()设置的顺序进行删除。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接