How to delete dynamic objects (creating by operator new)? Freed memory by the operating system or some Qt-means? Thanks.
How to delete dynamic objects (creating by operator new)? Freed memory by the operating system or some Qt-means? Thanks.
In general, any object instance that is created by operator new() and is given to another object instance as its child does not have to be deleted. Qt QObject parent-child relationships will ensure that when an instance's parent gets deleted, all of its children will be deleted, too.
Since most apps create QApplication and QMainWindow instances on the stack, in main(), when the program exits these instances and all of their heap-created children will be automatically cleaned up.
One exception to this is the use of heap-allocated QAction instances. One instance of a QAction can be shared with multiple object instances (such as assigning the same QAction instance to a menu, push-button, and toolbar button). These should be made member variables of some higher-level GUI class (such as your QMainWindow) and should be deleted in the destructor of that class. Assigning a QAction to a menu item does not establish a parent-child relationship.
Last edited by d_stranz; 10th October 2011 at 17:41.
I don't see any other questions:
You asked how to delete objects created using "new" operator. That's what you use the "delete" operator for.How to delete dynamic objects (creating by operator new)? Freed memory by the operating system or some Qt-means? Thanks.
It really pays off to invest some time in learning to write proper English sentences.
That's not true. I'd like to see you creating a QAction object as a member variable... QAction is by any means similar to other QObject subclasses, if you delete a parent of QAction, the action gets deleted too. The only difference is that QAction requires a parent (thus it makes no sense to make it a member variable of another QObject).One exception to this is the use of heap-allocated QAction instances. One instance of a QAction can be shared with multiple object instances (such as assigning the same QAction instance to a menu, push-button, and toolbar button). These should be made member variables of some higher-level GUI class (such as your QMainWindow) and should be deleted in the destructor of that class.
In Qt Ex. and Demos objects-parent (of the first level) are dynamical objects and they are not removed by "delete" in destructors. Why?
Last edited by spherrra; 10th October 2011 at 17:55.
OK, you are probably right. In my MainWindow classes, I do create actions as children of this. But why does deleting them in the MainWindow destructor not cause a memory fault? If the action instances were in fact first-class children of the MainWindow instance, shouldn't they have already been deleted by the QObject system before it gets to my destructor? (Or if destruction occurs in the reverse order, shouldn't my deletes cause a fault somewhere further up the line as destructors for MainWindow's superclasses get invoked?)
And by "member variable" I meant that the member variable is a QAction *, not QAction.
If the QObject system guarantees that QAction instances are also deleted when their parent goes out of scope, that would save me a lot of otherwise useless member variables.
In most of the demos that I have looked at, the base object of the GUI is derived from QMainWindow or QDialog, and is allocated on the stack in the main() procedure. Any child that is created further down in the code is created as a child of this main window, and is therefore owned and and has its lifetime controlled by it.In Qt Ex. and Demos objects-parent (of the first level) are dynamical objects and they are not removed by "delete" in destructors. Why?
Last edited by d_stranz; 10th October 2011 at 18:05.
Children and members are two distinct things.
Why would it?But why does deleting them in the MainWindow destructor not cause a memory fault?
Think what is the order of destructor calls when using C++ inheritance.If the action instances were in fact first-class children of the MainWindow instance, shouldn't they have already been deleted by the QObject system before it gets to my destructor?
Here a pointer to an object is a member variable, not the object itself. You can have 10 pointers pointing to the same object and all these can be member variables of different objects. The pointed object doesn't have to be a member variable of any object.And by "member variable" I meant that the member variable is a QAction *, not QAction.
Pardon me for using imprecise terminology. I have a bit more than 20 years of C++ experience, and I understand the differences between heap and stack allocated objects, and how pointers and references work. I do remember the order in which destructors are called but if you write semantically correct code it doesn't usually matter.
And IMO, a "member variable" can be a value that is stack-allocated during construction, a reference assigned during construction, or a pointer to a heap-allocated instance created and assigned at any time during the lifetime of an object instance. You imply that it is only the first type. If so, then what do you call a pointer variable that is defined as a member of a class if not a "member variable"?
Nomenclature aside, if I create a pointer to a QObject type using another QObject instance as its parent, store that pointer in a pointer member variable of that class, then delete that pointer in my class destructor, why doesn't that cause a memory fault? Creating that pointer and setting my class instance as its parent presumably stored it away somewhere in Qt's object hierarchy system with a flag that says, "when this parent goes out of scope, delete this child, too". So, if I delete it first, then that leaves a dangling pointer which should cause a memory fault when Qt tries to delete it later. Why not? Is the QObject constructor written in such a way that deleting a QObject instance also removes it from any parent-child relationship it might be in?
If this is true, then is there ever a case in Qt where a call to delete is required, except at the very top of a heap-allocated object hierarchy?
For example: Qt 4.7 Examles and Demos, OpenGL, Hello GL Example
There are two classes GLWidget and Window. I cite the file window.cpp
The object "glWidget" is dynamical. But it is not the object-child of object of the Window. I must so writteQt Code:
Window::Window() { glWidget = new GLWidget;To copy to clipboard, switch view to plain text mode
Qt Code:
Window::Window() { glWidget = new GLWidget(this);To copy to clipboard, switch view to plain text mode
or writte destructor
But it's not in this example. Why?Qt Code:
Window::~Window() { delete glWidget;To copy to clipboard, switch view to plain text mode
Look at these lines:
Qt Code:
mainLayout->addWidget(glWidget); // ... setLayout(mainLayout);To copy to clipboard, switch view to plain text mode
This first line creates a QHBoxLayout. The second line assigns it as the parent of glWidget. The third line assigns Window as the parent of mainLayout. So, mainLayout is owned by Window, and glWidget is owned by mainLayout. Each of these children will be deleted automatically when Window goes out of scope.
spherrra (10th October 2011)
Ok. Thank you! I understood this. СпаÑибо![]()
I didn't say anything like that. I said the pointer is a member variable and not the object it points to. If you have "int *x" then the variable which is a memeber of the object that contains it is "x" and not "*x".
Because QObject destructor is called after your destructor and the object you delete has time to detach itself from its parent and thus is not deleted again when the parent is deleted. The code is equivalent to:Nomenclature aside, if I create a pointer to a QObject type using another QObject instance as its parent, store that pointer in a pointer member variable of that class, then delete that pointer in my class destructor, why doesn't that cause a memory fault?
Qt Code:
if(parent()) parent()->children().remove(this); // of course ignoring that children() returns a copy m_parent = newParent; if(m_parent) m_parent->children().append(this); // of course ignoring that children() returns a copy }To copy to clipboard, switch view to plain text mode
A call to delete is only required if a QObject-derived (and heap allocated) object has no parent (and is not assigned to some kind of smart pointer). I usually have 0 QObject-related "delete" calls in my programsIf this is true, then is there ever a case in Qt where a call to delete is required, except at the very top of a heap-allocated object hierarchy?
Oh... one more thing. Never create QObjects with a parent on the stack (unless they are modal QDialogs which is usually safe). Then you can have double deletions (the behaviour is compiler-dependent).
Added after 8 minutes:
To be exact:
Qt Code:
#include <QtGui> int main(int argc, char **argv){ l->addWidget(w); qDebug() << ( w->parent() ? w->parent()->metaObject()->className() : "no parent"); QDialog dlg; dlg.setLayout(l); qDebug() << ( w->parent() ? w->parent()->metaObject()->className() : "no parent"); qDebug() << ( l->parent() ? l->parent()->metaObject()->className() : "no parent"); return 0; }To copy to clipboard, switch view to plain text mode
yields:
The child widget is reparented to the widget and not to the layout.no parent
QDialog
QDialog
Last edited by wysota; 10th October 2011 at 19:33.
spherrra (10th October 2011)
OK, thanks. This is exactly what I was referring to when I asked if deleting a child removed it from its parent's list of children. So my "extra" deletes do no harm (but don't do much good, either). Away with them!Qt Code:
if(parent()) parent()->children().remove(this); // of course ignoring that children() returns a copy m_parent = newParent; if(m_parent) m_parent->children().append(this); // of course ignoring that children() returns a copy }To copy to clipboard, switch view to plain text mode
Ok, I had known that also, but was trying to keep the explanation more simple.The child widget is reparented to the widget and not to the layout.
Sure, but in two years from now somebody would put the following post right under yours:
Hi d_stranz, so glad I have found this forum!
I'm a newbie in Qt and a newbie in C++. I have written the following code:
Qt Code:
int main(...) { l->addWidget(w); delete l; }To copy to clipboard, switch view to plain text mode
According to what you have said when "l" is deleted, it should delete "w" but it doesn't! I'm using Qt 5.2.7. Is this a bug in Qt? Should I report it to <whoever owns Qt in two years>?
d_stranz (10th October 2011)
Point taken.
That'll be either Google or Microsoft. (or maybe Oracle... no, Ellison couldn't be that greedy).<whoever owns Qt in two years>
Bookmarks