8.2.2.  QObject's Child Managment

[ fromfile: children.xml id: qobjectchildmgmt ]

Example 8.2 shows a QObject derived class.[67]

Example 8.2. src/qobject/person.h

[ . . . . ]

class Person : public QObject {
 public:
    explicit Person(QString name, QObject* parent = 0);
    virtual ~Person();
};
[ . . . . ]

<include src="src/qobject/person.h" href="src/qobject/person.h" id="personh" mode="cpp"/>


The complete implementation is shown in Example 8.3. Notice that ~Person() does no explicit object deletion. It simply displays the name of the object being destroyed (for teaching purposes).

Example 8.3. src/qobject/person.cpp

#include "person.h"
#include <QTextStream>

static QTextStream cout(stdout);

Person::Person(QString name, QObject* parent)
         : QObject(parent) {
    setObjectName(name);
    cout << QString("Constructing Person: %1").arg(name) 
         << endl;
}

Person::~Person() {
    cout << QString("Destroying Person: %1").arg(objectName()) 
         << endl;
}

<include src="src/qobject/person.cpp" href="src/qobject/person.cpp" id="personcpp" mode="cpp"/>


growBunch(), shown in Example 8.4, creates some objects, adds them to other objects, and then exits. All its local objects get destroyed when growBunch() returns.

Example 8.4. src/qobject/bunch.cpp

[ . . . . ]
void growBunch() {
    qDebug() << "First we create a bunch of objects." << endl;
    QObject bunch;
    bunch.setObjectName("A Stack Object");  1
    /* other objects are created on the heap */
    Person* mike = new Person("Mike", &bunch);
    Person* carol = new Person("Carol", &bunch);
    new Person("Greg", mike);               2
    new Person("Peter", mike);
    new Person("Bobby", mike);
    new Person("Marcia", carol);
    new Person("Jan", carol);
    new Person("Cindy", carol);
    new Person("Alice");                    3
    qDebug() << "\nDisplay the list using QObject::dumpObjectTree()"
             << endl;
    bunch.dumpObjectTree();                 4
    cout << "\nReady to return from growBunch() -"
         << " Destroy all local stack objects." << endl;
}


int main(int , char**) {
   growBunch();
   cout << "We have now returned from growBunch()."
        <<  "\nWhat happened to Alice?" << endl;
   return 0;
}
[ . . . . ]

1

A local stack object - not a pointer

2

We do not need to keep pointers to children, because we can reach them via object navigation.

3

Alice has no parent - memory leak?

4

dumpObjectTree() output will appear on the screen only if the Qt library has been compiled with the debugging option turned on.

<include src="src/qobject/bunch.cpp" href="src/qobject/bunch.cpp" id="bunchcpp" mode="cpp"/>


Following is the output of this program.

src/qobject> ./qobject
First we create a bunch of objects.
Constructing Person: Mike
Constructing Person: Carol
Constructing Person: Greg
Constructing Person: Peter
Constructing Person: Bobby
Constructing Person: Marcia
Constructing Person: Jan
Constructing Person: Cindy
Constructing Person: Alice

Display the list using QObject::dumpObjectTree()
QObject::A Stack Object
    QObject::Mike
        QObject::Greg
        QObject::Peter
        QObject::Bobby
    QObject::Carol
        QObject::Marcia
        QObject::Jan
        QObject::Cindy

Ready to return from growBunch() - Destroy all local stack objects.
Destroying Person: Mike
Destroying Person: Greg
Destroying Person: Peter
Destroying Person: Bobby
Destroying Person: Carol
Destroying Person: Marcia
Destroying Person: Jan
Destroying Person: Cindy
We have now returned from growBunch().
There is no way to access Alice.
src/qobject>


[67] This example is based on an American TV sitcom that originally aired from 1969 to 1974 and was in syndication for decades after that. If you were born too late to view it, you can get a bit of the flavor of it from this Wikipedia article.