Should destructor be called on member objects [duplicate] - c++

This question already has answers here:
Do I have to delete it? [Qt]
(3 answers)
Closed 4 years ago.
When looking at Qt examples (on Qt documentation like movieplayer example, or here), I never see the member destructors explicitly called.
A class definition is like:
class foo : public QParent {
Q_OBJECT
QStuff stuff;
foo (QWidget *parent) : QParent(parent)
{
stuff = new QStuff(this);
}
};
My problem is that I never see something like delete stuff;
So my questions are:
Are QObject derived class instances which parent is not NULL automatically deleted when their parent is?
Is it dangerous to delete a QObject derived member without setting it to NULL?
I guess the answers are Yes and No, but I'm not sure.

For the first question yes. You can check the Qt docs here
where it is stated clearly:
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. You can look for an object by name and optionally type
using findChild() or findChildren().
For the second question, the answer deserves a little bit more of explanation. If you have QObject pointers members that are not children of your object, you have to handle their disposal manually in the destructor of your class.
You can in theory use delete on any QObject* to invoke its destructor, but since Qt objects have a powerfull event system based on signals/slots, you must be aware of the interactions with event loops. If you brutally delete a QObject connected to another QObject while the latter one is still processing a signal coming from the first one, you may end up with some problems.
This holds in both mono and multi-threaded applications. You should therefore avoid the use of delete in favor of QObject::deleteLater() that will defer the deletion of the QObject until all the signal/slots related to it have been processed.
Lastly, in the context of the implementation of a destructor it doesn't really matter if you set the pointer to null, because it will be unavailable for further use anyway. It may be important if you delete the pointee in some other method, while your instance is still alive, and you set the pointer to null to flag it as uninitialized.

No, you do not need to delete member objects. They will get destroyed automatically when the parent class object gets destroyed.
See this FAQ.
In the case of Qt QObject pointer members, then the parent is the owner and is responsible for deleting the QObject. See here.

Related

Qt - What is the best way to keep a pointer to something stored in a QList?

I am pretty new to Qt and C++ (been working on C# and Java all my life) and I have been reading almost everywhere that I shouldn't use raw pointers anymore (beside the ones in constructors and destructors, following RAII principle).
I am okay with it but there is a problem that I cannot easily resolve without pointers.
I'll try to explain my problem.
I am creating a QList of a custom class created by me (MyClass) that will act as a model for my application:
QList<MyClass> modelList;
This QList is updated (items added, removed or updated) by a worker thread on the basis of the information arriving from the network.
So far so good.
Now I have another thread (GUI one) that has a QList of drawable items (MyDrawableItem). Each of these items has a member that must point to one of the items in the first QList (modelList), like this:
QList<MyDrawableItem> listToDraw;
where:
class MyDrawableItem
{
private:
MyObject *pointedObject;
//List of many other members related to drawing
}
because everytime a timer in the GUI thread expires I have to update the drawing related members on the basis of the pointed object. Must note that it is safe to keep a pointer to members of QList as stated in the documentation:
Note: Iterators into a QLinkedList and references into heap-allocating
QLists remain valid as long as the referenced items remain in the
container. This is not true for iterators and references into a
QVector and non-heap-allocating QLists.
Internally, QList is represented as an array of T if sizeof(T) <=
sizeof(void*) and T has been declared to be either a Q_MOVABLE_TYPE or
a Q_PRIMITIVE_TYPE using Q_DECLARE_TYPEINFO. Otherwise, QList is
represented as an array of T* and the items are allocated on the heap.
How could this be feasible without using pointers? Or even better what should be the best way to do this kind of work?
I found three possible solutions:
Instead of keeping pointedObject as member of MyDrawableItem, keep the index of the pointed object in the modelList. Then on the update go look inside the QList. But what if the item in the list is removed? I could signal it but if the update happens before the slot is called?
Don't keep anything at all as a member and connect two signals to MyDrawableItem. One signal is updateDrawing(const MyObject&) that updates the drawing-related members and another signal is removeDrawing() that simply deletes the object. This way I don't have to worry about the syncronization between the threads because the MyDrawableItem object won't ever look at the content of the QList. In this case I could be updating the item very often with lots of signals while I only want to update the GUI once in a while (timer of 500 ms).
Simply use pointers.
Evolve and use QSharedPointers but I have never used those and I don't know if that is the best option.
I think that neither of these solutions is the perfect one so I am here asking for your help.
How do the standard views in Qt (tableview, listview, ecc.) deal with this problem?
How should I deal with it?
Please help me, I am thinking about this from yesterday and I don't want to make a mess.
Thanks a lot!
An addition to #Benjamin T's answer:
If you do decide to go for option 4 and use QSharedPointer (or the std variant), you can actually control ownership somewhat using "weak pointers". Weak pointers store a reference to the object, but do not own it. Once the last "strong pointer" gets destroyed, all the weak pointers drop the reference and reset themselves to nullptr.
For your concrete example, you could use a QList<QSharedPointer<MyClass>> for the model and use QWeakPointer<MyClass> in the drawable classes. Before drawing you would create a local QSharedPointer<MyClass> in the drawing function and check if it is valid.
I would still recommend you to use 2/3, as recommended by Benjamin. Just a small addition.
It is the current trend among the C++ community, especially if you look at all the CppCon conferences to discourage the use of raw pointers.
This trend is not without sold basis, as the use of std::shared_ptr and std::unique_ptr as well as std::make_unique and std::make_shared can help a lot memory management and prevent some pitfalls (like having an exception thrown during a call to a constructor).
However, there is nothing absolute in this "do not use raw pointers" trend and raw pointers can still be used and smart pointers do not solve all memory management problems.
Concerning the case of Qt, if you are dealing with QObject derived class and you properly parent your objects you are kind of safe as you have an owning hierarchy and parents QObjects will destroy their children. This is very important if you are also using QThread as QObject instances are associated with a QThread and all instances in a QObject hierachy are associated with the same thread.
Regarding your solutions:
Bad idea, you need to sync your list and the indexes all the time.
It could be an idea, but it changes the architecture of your software. Does MyObject really needs to know about MyObject ? If the answer is 'no', signal/slots seems a better solution. It might indeed require some work to solve your refresh rate issue, but this is off-topic.
It might look like a good idea, especially if your objects are inheriting QObject. Also you may want to use QVector<T *> and std::vector<T *> and let the QObject hierarchy deals with life span of your objects. You can listen to the destroyed() signal to know when the object are destroyed, or use QPointer. However, it does not solve the thread safeness on your consumer side, as the object might be deleted at any point in time from another thread.
If you cannot do 2, this is the option to go for. You just have to take care to not have cyclic dependencies or you will leak memory. However, this might be a bad idea if you want that when you delete an object in your list then it gets removed from your GUI object. If you simply keep a shared pointer, you will never know that it was removed from the list. As stated by #Felix, you can store weak pointers and convert them to shared pointers only when needed, but if you have consumers in multiple threads, then you may never delete the object. Also you have to make MyObject thread-safe as you are mutating it states from one thread and reading it from another thread. Using option 4 does change the owning model of your software: in the current state the QList owns the instances, with option 4 the ownership is shared with anyone getting a shared pointer.
My personal choice would be to replace the QList with a QVector of pointers.
If your objects inherit from QObject, then I would parent all the objects in the QVector to the object that owns the QList/QVector. This is to ensure proper parenting and thread association.
Then I would try option 2, and only if option 2 fails go for option 4.
Here is an exemple:
class MyClass : public QObject
{
Q_OBJECT
public:
explicit MyClass(QObject *parent = nullptr);
signals:
void stateChanged(int state);
};
class Owner : public QObject
{
Q_OBJECT
public:
explicit Owner(QObject *parent = nullptr);
void addObject(MyClass *obj) {
obj->setParent(this);
m_objects.append(obj);
}
void removeObject() {
delete m_objects.takeFirst();
}
private:
QVector<MyClass *> m_objects;
};
class Consumer : public QObject
{
Q_OBJECT
public:
explicit Consumer(QObject *parent = nullptr);
public slots:
void onStateChanged(int state) {
m_cachedState = state;
}
private:
int m_cachedState = 0;
};
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QThread thread;
thread.start();
Owner owner;
Consumer consumer;
consumer.moveToThread(&thread);
MyClass *object = new MyClass();
owner.addObject(object);
QObject::connect(object, &MyClass::stateChanged, &consumer, &Consumer::onStateChanged);
return app.exec();
}

Qt object ownership memory leak

I am reading an introduction book to Qt and I am writing this code:
server.h
class server : public QObject {
Q_OBJECT
private:
QTcpServer* chatServer;
public:
explicit server(QObject *parent = nullptr) : QObject(parent) {}
//more code...
};
#endif // SERVER_H
Then the book suggests to create the object in this way:
chatServer = new QTcpServer(); //<-- ?)
chatServer->setMaxPendingConnections(10);
I have read online that Qt has an hierarchy because everything descends frm QObject and the parent object will take care of the life of the children. In this case, doesnt the code generate a memory leak?
Because chatServer = new QTcpServer(); is equal to chatServer = new QTcpServer(nullptr); and so I am not specifying a parent! So there is nobody that takes care of the life of this object in the heap. Do I have to call the delete (or better use an unique_ptr ) to manage the memory?
Another fix that I'd use would be chatServer = new QTcpServer(server);. Would this be ok?
If this code is indeed all that's shown in your book, then you are correct. If you don't pass the parent to QTcpServer it won't be automatically deleted when your object is destroyed. You can also do that manually in the destructor or maybe even better - just don't use the pointer and use it directly (though you may need to use pointer if you, for example, decide to move the object to another thread).
This does indeed seem to be a memory leak. chatServer should have this as its parent so it will be automatically destroyed with the server object:
chatServer = new QTcpServer(this);
chatServer->setMaxPendingConnections(10);
// ... more code
Assuming that this happens inside a member function of the server class, this would parent the QTcpServer object to the server object.
If the book provides no specific reason to make the QTcpServer object dynamically allocated, it is probably not necessary. In that case, as Dan M. says, it is entirely possible to not use a pointer at all and simply have QTcpServer chatServer
In the example you posted, you have to take care of the pointer for yourself.
But instead of calling delete, you may want to use the QObject's slot deleteLater.

Deleting object that inherits from QWidget, WA_DeleteOnClose segmentation fault

I'm using an object the inherits QWidget, and in order to know when it is closed, I've used setAttribute(Qt::WA_DeleteOnClose), and connected
connect(myObj,SIGNAL(destroyed(QObject*)),this,SLOT(handleFinish()));
However, when the object is being deleted, I get munmap_chunk(): invalid pointer, and when I look at the address of the pointer, it is one of the data members of myObj, which is really not a pointer.
I allocate myObj dynamically, so it is supposed to be on the heap - myObj = new myObj();
The error comes at the end of myObj destructor, and I've checked that this is the first time the destructor is called (after looking at When setting the WA_DeleteOnClose attribute on a Qt MainWindow, the program crashes when deleting the ui pointer).
Any suggestions for dealing with it?
By the time you receive the destroyed signal, the object is only a QObject - not a QWidget and definitely not of any derived type. You can only access the members and methods provided via QObject, not via any other type.
It seems that you wish to be notified when a widget is about to close: for that, install an event filter that intercepts QEvent::close on the widget. See also this answer and a discussion of why a closeEvent cannot be generally handled via a slot.

Qt - How a QObject with a parent on the stack might get deleted twice?

Can someone explain the following please?
Stack or Heap?
In general, a QObject without a parent should be created on the stack or defined as an subobject of another class. A QObject with a parent should not be on the stack because then it might get deleted twice accidentally. All QObjects created on the heap should either have a parent, or be managed somehow by another object.
Source: LINK
Sorry, downvoting the accepted answer. Both versions as currently explained are wrong, and especially the conclusion is very wrong.
Parent/child for memory management
Amongst other things, Qt uses the parent/child concept to manage memory. When an object is parented to another one, then
deleting the parent will also delete (via operator delete) all of its children. Of course, this works recursively;
deleting a child will un-parent it, so that the parent will not attempt a double deletion. deleteLater is not required for this to work -- any deletion will un-parent it.
This allows you to build a tree of QObjects via repeated dynamic allocations through operator new, and not having the problem of having to manually delete all the allocated objects. Just give them parents, and you'll only have to delete the root of the tree. You can also delete a child (i.e. a subtree) at any time, and that will do the right thing™.
In the end, you will have no leaks and no double deletions.
This is why in constructors you'll see things like:
class MyWidget : public QWidget // a QObject subclass
{
Q_OBJECT
public:
MyWidget(QWidget *parent = nullptr);
// default destructor is fine!
private:
// raw pointers:
// we won't own these objects through these pointers.
// we just need them to access the pointees
QTimer *m_timer;
QPushButton *m_button;
};
void MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
{
// don't need to save the pointer to this child. because reasons
auto lineEdit = new QLineEdit(this);
auto validator = new QIntValidator(lineEdit); // a nephew
// but let's save the pointers to these children
m_timer = new QTimer(this);
m_button = new QPushButton(this);
// ...
}
The default destructor will properly delete the entire tree, although we allocated the children objects through calls to operator new, and we didn't even bother to save in members the pointers to some children.
QObjects on the stack
You are allowed (and in certain contexts it's actually a good idea) to give parents to objects allocated on the stack.
The typical example is of QDialog subclasses:
void MyWidget::showOptionsDialog()
{
// OptionsDialog is a QDialog subclass;
// create an instance as a child of "this" object
OptionsDialog d(this);
// exec the dialog (i.e. show it as a modal dialog)
conts auto result = d.exec();
if (result == QDialog::Accept) {
// apply the options
}
// d gets destroyed here
// => it will remove itself as a child of this
}
The purpose of passing this as the dialog's parent is to allow the dialog to be centered upon the parent's widget, share the task tray entry, and be modal against it. This is explained in QDialog docs. Also, ultimately, d does only need to live in that function, so it's a good idea to declare it as an automatic variable (i.e. allocated on the stack).
There you go: you've got a QObject, allocated on the stack, with a parent.
So what's the danger of QObjects on the stack? Consider this code:
QObject *parent = new QObject;
QObject child(parent);
delete parent;
As explained before, parent here will attempt to call operator delete on child, an object which was not allocated using new (it's on the stack). That's illegal (and a likely crash).
Obviously, nobody writes code like this, but consider the dialog example above again. What if, during the call d.exec(), we manage somehow to delete this, that is, the dialog's parent? That could happen for a variety of reasons very, very difficult to track down -- for instance, data arrives on a socket which causes widgets in your UI to change, creating some and destroying others. Ultimately, you would delete a stack variable, crashing (and having an extremely hard time trying to reproduce the crash).
Hence the suggestion to avoid creating code like that in the first place. It's not illegal, it may work, but it may also not work, and nobody likes fragile code.

Qt code questions perhaps pertaining to C++ in general

I have recently began working with the Qt framework and realized there may be a bit about the syntax of C++ that I do not quite understand. Take for example this code that is given as a foundation when starting a Widget project in Qt.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
Where the class MainWindow is defined as:
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
Class declaration
Stepping through this, I can see that a new namespace, Ui, is created. I imagine this to be an implementation effort to avoid naming conflicts with other user-implemented classes.
A new class definition follows; it inherits QMainWindow, so we are essentially creating a custom window object.
Q_OBJECT is apparently a macro that allows the user to use signals and slots in the class definitions, but I am not too worried about that code right now.
We define the constructor to be explicit thereby disallowing any implicit conversions of this class type. There is also a destructor shown.
In the private accesses, we look to the Ui namespace and create a MainWindow pointer.
Class definition
We are using an initialization list I see, but I get lost here. I see that we have a default parameter of NULL ( or 0 ) for the parent of this widget, but if a class inherents another class why must you explicitly call the constructor for said inherited class? That is:
class A {
}
class B : public A {
}
B testObject;
Does this not automatically allocate memory on the stack sufficient memory to contain both classes A and B? Why does the Qt code shown above call the constructor for an inherited class within its own constructor?
Continuing to the second parameter of the initialization list, I must say that I am confused on the syntax used here. Why do we have a pointer to a QMainWindow that we initialize by calling QMainWindow's constructor with a further call to new thereby creating an instance of itself? This initialization method seems circular.
We then call a setupUi function and pass this object for initialization.
And finally, in the destructor we simply deallocate the memory associated with the MainWindow.
As a final question, if an additional object is created, say a QPushButton, does the software automatically deallocate the memory assocated with these objects or must that be included in the destructor alongside delete ui? I have not seen a tutorial that actually does this, so I am not sure if the framework is designed such that it is handled for you.
I know there are few direct questions here, but is there any flaw in my logic for each statement?
tl;dr, skip to the first and second bullet under Class definition.
Please note that you should not ask so many sub-questions in a question, but I will try to answer your questions regardless ...
Does this not automatically allocate memory on the stack sufficient memory to contain both classes A and B?
It allocates memory for the base class, yes.
Why does the Qt code shown above call the constructor for an inherited class within its own constructor?
Because that is how C++ inheritance works. You need to initialize the base class explicitly in cases like this It could be implicit in an ideal with default constructors, but you are not even using that in here which is good.
Why do we have a pointer to a QMainWindow that we initialize by calling QMainWindow's constructor with a further call to new thereby creating an instance of itself? This initialization method seems circular.
As you explained in the beginning, you have two separate MainWindows, one generated by the Qt Designer, and one class implementation in your code, thus the namespaces you mentioned.
As a final question, if an additional object is created, say a QPushButton, does the software automatically deallocate the memory assocated with these objects or must that be included in the destructor alongside delete ui? I have not seen a tutorial that actually does this, so I am not sure if the framework is designed such that it is handled for you.
If you allocate it on the stack, it is not necessary since it will be destroyed automatically when running out of scope. If you allocate that on the heap, in the Qt world, you specify the parent as the argument for the constructor so that it gets deleted automatically when the parent gets deleted. This is done transparently for you by the Qt parent-child hierarchy and mechanism. That is why you do not see explicit delete usually in examples.