CopperSpice API  1.9.2
Object Trees and Ownership

QObjects are organized as tree of objects. When you create a new QObject with another object as it sparent, the new object is added to the parent's list of children. When the parent is deleted all child objectes are deleted. For example, a QShortcut will be added as child of a window so when the user closes the window, the shortcut object is automatically destroyed.

QWidget is the base class of every element which appears on a screen. Child widgets are displayed using the parent's coordinate system and are usually graphically clipped to the parent widget's boundaries. As an example, when a QTabWidget is closed all child widgets displayed on that tab will destroyed.

If a child object is deleted before its parent the parent object will be notified and the list of child objects will be updated. For example, when the user removes a toolbar the parent will receive a signal and the slot method can reconfigure the layout accordingly.

Construction / Destruction Order of QObjects

When multiple QObjects are created on the heap using new, the objects can be constructed in any order. The myWindow object is the parent and closeButton is the child object. Destroying myWindow will destroy closeButton.

int main()
{
QWidget *myWindow = new QWidget();
QPushButton *closeButton = new QPushButton("Close", myWindow);
delete myWindow;
}

When QObjects are created on the stack the order of construction must be considered. In the following code, myWindow is again the parent object and closeButton is the child object. At the end of the function local objects are destroyed in the reverse order of their construction.

The destructor of closeButton happens first and removes itself from the parents list of children. When myWindow is destroyed is has no children so this is correct code.

int main()
{
QWidget myWindow;
QPushButton closeButton("Close", &myWindow);
}

If we swap the order of object construction as shown below, a problem occurs. The myWindow object will be destroyed first, since it was constructed last. During this process of destroying myWindow the parent will destroy the closeButton object.

The clean up code, which the compiler generated, has no knowledge the closeButton has already been destroyed and will attempt to destroy again. This is undefined behavior and there is no telling what will happen. If your code declares a QObject on the stack you must ensure child objects are declared after their parents.

int main()
{
QPushButton closeButton("Close");
QWidget myWindow;
closeButton.setParent(&myWindow);
}