Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QObject auto delete order

Tags:

c++

qt

I have example code:

#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();
}

Execution of above app gives me this results:

destructor A
destructor B
destructor C

What is the order of auto(qt) destruction operations?

Can I assume order of destruction(B, C) is same as order of creation(new B(a), new C(a))?

Why order of destruction is not: A, C, B?

like image 778
exfoo Avatar asked Jun 03 '26 03:06

exfoo


2 Answers

Once delete is called on a, its children b and c are delete'd as well, in the same order in which they were added to a's children collection. To demonstrate this, you can create b and c without the parent argument, then call setParent later: the order of destruction will be the same order of the calls.

like image 61
p-a-o-l-o Avatar answered Jun 05 '26 20:06

p-a-o-l-o


There are two pieces of information needed to answer your question. First is the order in which children are added. From the docs for QObject::children():

The first child added is the first object in the list and the last child added is the last object in the list, i.e. new children are appended at the end.

Then from the QObject destructor, the deleteChildren() function does:

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

So it deletes them in the order they're added to the list of children.


This is true for every QObject subclass except the UI objects, i.e., QWidget and its subclasses. Again from the docs:

Note that the list order changes when QWidget children are raised or lowered. A widget that is raised becomes the last object in the list, and a widget that is lowered becomes the first object in the list.

So calling raise() or lower() manipulates the list, so the order in which they're deleted is no longer so simple. But for non-UI objects, they're deleted in the order their given the parent, either in their constructor or by doing QObject::setParent().

like image 44
bnaecker Avatar answered Jun 05 '26 20:06

bnaecker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!