Creating and deallocating a Qt widget object - c++

I heard that the widgets should be allocated on the heap (using new), and then there are no needs to delete them (it is done automatically).
Can someone explain why?
What happens if a widget is not allocated that way, but on a stack?
I am not sure if it matters, but all widgets I am creating have a parent.
This says :
If parent is 0, the new widget becomes
a window. If parent is another widget,
this widget becomes a child window
inside parent. The new widget is
deleted when its parent is deleted.

There's no magic involved. Simply put, a QObject automatically deletes its children in its destructor. So, as long as your widget has a parent and that you destroy that parent, you don't have to worry about the children. So if you wondered what was that QObject * parent parameter, well, that's what it's there for.
Also, from the doc:
All child objects are deleted. If any of these objects are on the stack or global, sooner or later your program will crash.
So, avoid giving parents to objects that are stack-allocated.

The docs on this are here. The reason they are most often allocated on the heap is to avoid problems caused by construction order of the members of the object tree. The stack is fine so long as you follow the rules, but why bother when you have a reliable alternative?
The reference #Etienne cited is here.

Related

Can I use QCoreApplication::instance() for Orphan QObjects?

For QObjects created on the heap with no parent, I found that destructor is not called. So, I starting using the core application instance as their parent to ensure that they are cleaned by garbage collector. Is this the right action, or what should I exactly to safely de-allocated these objects?
Here is an example of what I am doing:
// Use application instance as parent to avoid memory leak if object is not deleted
m_qObject = new DataHandler(QCoreApplication::instance());
Qt doesn't have an independent memory management, such as a garbage collector. The explicit parent-child relationship used is a classic ownership model that helps in the automatization of object life-cycles, it is deterministic (it will delete object on parent's destruction), and it is very natural with user interfaces.
If an object is created (in the heap) without a parent, it will generate a memory leak when the last reference to it is lost. Objects in the stack should not have a parent to prevent double-delete errors (check Qt documentation for further information)
If you set QApplication::instance as the parent of an object, you are basically telling it not to be destroyed until the application quits. If that's the case, then there is no such a great difference with other standard memory leaks, escept the object's destructor does something else than just releasing memory (such as closing OS-wide handles, saving files, etc).
There is a very interesting case I was curious about: what happened when the original parent (Q*Application::instance) was replaced at any given moment, as in this question?
The case is that the ownership of the object is transferred from the former Q*Application instance to the new one. It may become a problem if you rely on the existence of the object through the whole application life-span but several instances of Q*Application are allowed to be created and destroyed at any moment. One scenario would be a non-Qt application loading plug-ins or components built on Qt, in where you cannot control the creation/destruction order.
If that's the case, I'd suggest to find another way to destruct your object, such as having your own singleton inheriting from QObject that you can use as parent.

When do I use pointers in Qt?

Ive been programming Qt for a while now and I am wondering what the difference is between these two cases:
case1:
header:
QPushButton * button;
source file:
button = new QPushButton(this);
button->setText("Button");
button->resize(100,100);
and
case2:
header:
QPushButton button;
source:
button.setParent(this);
button.setText("Button");
button.resize(100,100);
Both produce a button, but when should I use the former and when the latter case? And what is the difference between the two?
The difference between the first and second case is that when you use pointers and the new statement to allocate the button, the memory for the button is allocated in the free store (heap). In the second statement the memory is allocated on the stack.
There are two reasons why you would rather allocate memory in the free store than the stack.
The stack is of limited size and if you blow your stack budget your program will crash with a stack overflow. One can allocate much more memory in the free store and if a memory allocation fails, all that normally happens is that a bad_alloc exception is thrown.
Allocation on the stack is strictly last in first out (LIFO) which means that your button cannot exist for longer than the code block (whats between the {...} ) that allocated the memory. When memory is allocated in the free store, you as the programmer have full control of the time that the memory remains valid (although carelessness can cause memory leaks)
In your case, if the button just needs to exist for the duration of the calling function, you will probably be ok allocating the button on the stack; if the button needs to be valid for much longer stick to the free store
Qt memory management works with hierarchies of objects, when parent object deletes child objects automatically on destroying. This is why Qt programs always use pointers in similar cases.
Memory Management with Qt:
Qt maintains hierarchies of objects. For widgets (visible elements) these hierarchies represent the stacking order of the widgets themselves, for non-widgets they merely express "ownership" of objects. Qt deletes child objects together with their parent object.
In the first case you are dynamically allocating the button (which means that it will be destroyed when the parent is destroyed). In the second case the button will disappear when the code block ends (meaning it goes out of scope).
Use the first when you want to QObject, you are referring to, to last more than just the block in which it is created.
In the context of the class you are referring to (assuming the button is a member variable in both cases) it doesn't make much difference.
Also you may want to use pointers when using polymorphism.
An useful specific usage: when posting custom events, carrying detailed data, for instance:
/** support SWI... prolog_edit:edit_source(File) */
struct reqEditSource : public QEvent {
QString file;
QByteArray geometry;
reqEditSource(QString file, QByteArray geometry = QByteArray())
: QEvent(Type(User+1)), file(file), geometry(geometry) {}
};
you can 'fire and forget' them:
qApp->postEvent(this, new reqEditSource(files[i], p.value(k).toByteArray()));
The event will be deleted after its delivery.
Many functions in Qt that take an object as argument, actually take a pointer to an object. That's because passing an object "by value" would actually create a copy of the object (via copy constructor) and pass that copy! Creating a new copy of the object has a lot of overhead. At the same time, passing the object "by reference", i.e. as a pointer, will just pass a 32-Bit memory address, which is a very lightweight operation.

Does QObject distinguish between stack and heap allocated children when deleting?

According to the Qt documentation:
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.
For me that implies when a QObject is being deleted, it goes through and calls delete on all the pointers it stores in its children list.
However, it is not necessary for children to be dynamically allocated, and it is perfectly legal to build QObject trees with stack allocated objects.
According to standard specifications, calling delete on a pointer that does not point to a dynamically allocated object is undefined behavior, which may result in anything from "nothing" to a program crash.
IMO it is unlikely for QObject, which is pretty much the backbone of the almost the entire collection of Qt classes to rely on something that could produce undefined behavior.
So, does QObject distinguish between stack and heap allocated children when deleting? And if so, how exactly?
However, it is not necessary for children to be dynamically allocated,
and it is perfectly legal to build QObject trees with stack allocated
objects.
No. See QObject::~QObject():
Warning: All child objects are deleted. If any of these objects are on
the stack or global, sooner or later your program will crash.

Dynamic memory Deallocation in QT

How does the dynamically allocated pointers in QT coding are destroyed because we don't write a specific destructor for them?
To expand on Neox's answer, Qt has two methods for object management:
QObject tree structure
Managed pointer classes
And the two don't really mix very well for reasons which will become apparent.
QObjects can either be 'free' or have a parent. When a QObject has its parent set (either by providing the QObject constructor with a pointer to another QObject, or by calling setParent()) the parent QObject becomes the owner of the child QObject and will make sure any of its children are destroyed when it is. There are also several methods available to inspect child/parent relationships.
A separate method of managing dynamically allocated objects are the managed pointer classes which this paper explains quite well. To summarise though:
"The QScopedPointer class stores a pointer to a dynamically allocated object, and deletes it upon destruction" and is therefore good when you need objects which have clear and obvious ownership and lifetime.
"The QSharedPointer class holds a strong reference to a shared pointer [and] will delete the pointer it is holding when it goes out of scope, provided no other QSharedPointer objects are referencing it" and is therefore good when ownership is not as clear cut, but you want to make sure it doesn't get lost and become a memory leak. QWeakPointer can be used to share the pointer without implying any ownership.
As you can see, some of the guarded pointer classes can be used with a QObject tree, but you should make sure you read and understand the documentation thoroughly before doing so or you may end up with a corrupt data structure.
The short answer is:
QObjects organize themselves in object trees. When you create a QObject with another object as parent, it's added to the parent's children() list, and is deleted when the parent is.
Qt has a good docu about object hierarchy and ownership within the framework. You can read it here

Parent/Child class ownership semantics

I've been building a system with a parent object, where it creates various child objects, and each child object requires a master object to function. Now, so far, I've been creating shared_ptr<Parent> and Child*, so when the creator of Parent and all the Childs are gone, the Parent goes too.
But I'm re-designing my API so that Child can be created on the stack (previously it was just the heap). Now I'm unsure about what to do with Parents, as I don't see why they shouldn't also be creatable on the stack- in terms of their actual function- but what happens if Parent is destroyed and then someone tries to use a Child that they moved, copied, or allocated on the heap? Should I just throw an exception? Skip performing the operation? Or just stick to allocating Parents on the heap?
Here's the problem sentence
if Parent is destroyed and then someone tries to use a Child ...
If this is possible then you have shared ownership, which implies creation on the heap.
So, either you stick to heap allocation or drop the shared ownership semantics. There is no other way. weak_ptr is merely away of advertising the state of a shared object.
If you really want to do what you're advertising:
if Parent is destroyed and then someone tries to use a Child ...
This is going to cause a problem as #spraff mentioned.
The way to achieve what you are saying is to also make the Child a shared_ptr and allow a shared ownership between the Parent and also whatever else is trying to use the child...