Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining own destructor although class derives from QObject?

Tags:

c++

qt

Let's have a class Test and a class AnotherClass. Both derive from QObject.

Test.h:

class Test : public QObject
{
Q_OBJECT

public:
    Test(QObject* parent);
    ~Test();

private:
    AnotherClass* other;
};

class AnotherClass : public QObject
{
Q_OBJECT

public:
    AnotherClass(QObject* parent);
    ~AnotherClass();
};

Test.cpp:

Test::Test(QObject* parent) : QObject(parent) 
{
    other = new AnotherClass(this);
}

Test::~Test()
{
    delete other;
}

other should be automatically destroyed when the Test-instance is destroyed because Test is the parent of other, right?

  • Now should I delete other by myself in ~Test() or does it leave the program in an undefined stage because it tries to delete the same object twice?
  • What is the correct approach here?
like image 534
SimonH Avatar asked Jan 14 '16 10:01

SimonH


2 Answers

QObjects organize themselves in object trees. When you create a QObject with another object as parent, the object will automatically add itself to the parent's children() list. The parent takes ownership of the object; i.e., it will automatically delete its children in its destructor. See Object Trees & Ownership for more information.

Because you pass this pointer of Test object to AnotherClass constructor it means that you use Test object as parent of AnotherClass. Thus deleting Test object deletes also its child and you don't need to explicitly delete other.

However, in this case explicit deletion in the destructor doesn't cause double deletion because it causes unregistration from the parent's children() list.

like image 133
talamaki Avatar answered Sep 24 '22 22:09

talamaki


Apart from the fact that you have to make the destructor virtual, the Qt documentation says:

When QObjects are created on the heap (i.e., created with new), a tree can be constructed from them in any order, and later, the objects in the tree can be destroyed in any order. When any QObject in the tree is deleted, if the object has a parent, the destructor automatically removes the object from its parent. If the object has children, the destructor automatically deletes each child. No QObject is deleted twice, regardless of the order of destruction.

So you can delete the other class explicitly, but you don't have to. Either approach should work without double deletes.

By the way, you could also make the AnotherClass a simple member of Test instead of a pointer.

like image 30
hfhc2 Avatar answered Sep 23 '22 22:09

hfhc2