Here is my sample qt connect statement
connect(pHttpFetch, SIGNAL(Fetched(QByteArray)), this, SLOT(PrintData(QByteArray)));
Here the signal of first object is connected to the slot of the invoking(which makes the connect call) object.
I have the following things
The first object is a local object. The object is killed when control goes out of scope.
The invoking object will stay in memory throughout the application memory.
As I don't need the first object, is it fine to make it a local object ? ( I assume Qt magically keeps the object in memory)
Should I make a shared pointer to hold the object. Will destroy the object when not required ?
According to the Qt documentation
All signals to and from the object are automatically disconnected, and any pending posted events for the object are removed from the event queue.
And no, Qt doesn't "magically" keep the object in memory.
An object that doesn't exist anymore can't send signals. You should allocate memory for this object and keep a reference to it. Remember that if you gave your QObject a parent, then this parent will automatically handle the deletion of their child (but if you don't provide a parent, you'll have to delete it manually or use the deleteLater() slot of QObject)
Related
I am facing an issue with Qt's signal and slot concept, as it is working asynchronously. I'm currently passing a pointer to an object which is created right before emitting a signal. I need to do this, because all receiving slots should use this object and be able to use the same state. I'm now running into problems, because I can't find a way to free the object after all the connected slots were executed. Is there an option for this?
You can use QSharedPointer. It will destruct automaically the object its holding when no one is referencing it anymore.
In early Qt 5 versions I have to disconnect lambdas from signals as shown here: "Disconnecting lambda functions in Qt5".
Here I found the following statement:
There is no automatic disconnection when the 'receiver' is destroyed because it's a functor with no QObject. However, since 5.2 there is an overload which adds a "context object". When that object is destroyed, the connection is broken (the context is also used for the thread affinity: the lambda will be called in the thread of the event loop of the object used as context).
Does it mean I have no longer to disconnect lambdas with Qt5.2 or later?
Do I have to pass that context or is that done automatically?
Qt automatically removes all connections to or from an object when it is destroyed through QObject::~QObject(). So if you create a connection to a lambda, when the sending object is deleted, the connection is automatically cleaned up. You do not, and have not previously needed to, disconnect it yourself.
The context object that you are referring to is used when you require more fine grained control over the lifetime of the connection. This is used when you want the connection to be removed when another object is destroyed (the context object). This makes it easier to remove the connection if you need to do so before the sender is destroyed.
In summary: You do not need to manually disconnect lambdas, they are cleaned up automatically. You can use context objects to remove the connection before the sender object is destroyed.
QTcpSocket * QTcpServer::nextPendingConnection () [virtual]
The socket is created as a child of the server, which means that it is
automatically deleted when the QTcpServer object is destroyed. It is
still a good idea to delete the object explicitly when you are done
with it, to avoid wasting memory.
In my application, a QTcpServer lives for a long time (it disconnects from host when connection is closed but is never destroyed unless the program exits), and it accepts a lot of QTcpServer::nextPendingConnection and takes a lot of memory.
How should I delete the old QTcpSocket object before switching to the next pending one to save memory, while at the same time avoid double-delete?
Is delete ok in this case?
Is delete ok in this case?
Yes, thanks to the cleverness of Qt's object design.
In particular, QTcpSocket derives (eventually) from Object, and the QObject destructor method contains this code at the end:
if (d->parent) // remove it from parent object
d->setParent_helper(0);
So deleting the QTcpSocket object will automagically remove the QTcpSocket from the children-list of its parent object (in this case, the QTcpServer), so there will be no double-delete when the QTcpServer object is destroyed.
What are the lifetimes of Qt Objects?
Such as:
QTcpSocket *socket=new QTcpSocket();
When socket will be destroyed? Should I use
delete socket;
Is there any difference with:
QTcpSocket socket;
I couldn't find deep infromation about this, any comment or link is welcomed.
Qt uses parent-child relationships to manage memory. If you provide the QTcpSocket object with a parent when you create it, the parent will take care of cleaning it up. The parent can be, for example, the GUI window that uses the socket. Once the window dies (i.e. is closed) the socket dies.
You can do without the parent but then indeed you have to delete the object manually.
Personally I recommend sticking to idiomatic Qt and using linking all objects into parent-child trees.
Objects allocated with new must be released with delete.
However, with Qt, most objects can have a parent, which you specify as an argument to the constructor. When the parent is deleted, the child objects get deleted automatically.
If you don't want to pass a parent for some reason (because there is no QObject where it makes sense to own the socket object), you can also use a QSharedPointer to manage the lifetime.
Here, my signal declaration:
signals:
void mySignal(MyClass *);
And how I'm using it:
MyClass *myObject=new myClass();
emit mySignal(myObject);
Here comes my problem: Who is responsible for deletion of myObject:
Sender code, what if it deletes before myObject is used? Dangling Pointer
The slot connected to signal, what if there is no slot or more than one slot which is connected to the signal? Memory Leak or Dangling Pointer
How does Qt manage this situation in its build-in signals? Does it use internal reference counting?
What are your best practices?
You can connect a signal with as many slots as you want so you should make sure that none of those slots are able to do something you would not want them to do with your object:
if you decide to pass a pointer as a parameter then you will be running in the issues you describe, memory management - here nobody can to the work for you as you will have to establish a policy for dealing with allocation/deletion. To some ideas on how to address this see the Memory Management Rules in the COM world.
if you decide to pass a parameter as a reference then you don't have to worry about memory management but only about slots modifying your object in unexpected ways. The ideea is not to pass pointers unless you have to - instead use references if you can.
if you decide to pass a const reference then, depending on your connection type, QT will pass the value of the object for you (see this for some details)
avoid any problems and pass by value :)
See also this question for some thoughts about passing pointers in signals.
For your first question, use QPointer
For your second question,
If I understood clearly, even if you are sending myObject, you still have the reference myObject in the class where you are emitting the signal. Then how will it be a memory leak or a dangling pointer? You can still access the myObject from the emitted class, isn't?
Hope am clear..
Edit :
From your comments I believe you are releasing/deleting the objects in the slots. Now I assume your problem is, what if the (memory releasing) slot gets called once,twice or not called at all.
You can use QPointer for that. From the Qt documentation,
Guarded pointers (QPointer) are useful whenever you need to store a pointer to a QObject that is owned by someone else, and therefore might be destroyed while you still hold a reference to it. You can safely test the pointer for validity.
An example from the Qt documentation itself,
QPointer<QLabel> label = new QLabel;
label->setText("&Status:");
...
if (label)
label->show();
the explanation goes on like this..
If the QLabel is deleted in the meantime, the label variable will hold 0 instead of an invalid address, and the last line will never be executed. Here QLabel will be your MyClass and label is your myObject. And before using it check for Nullity.
At 1): The sender should take care. When sending the signal synchronously (instead of queued), the object is still alive when a receiver receives it. If the receiver needs to store it, only a QPointer would help, but then MyClass needs to derive from QObject, which looks wrong from the context.
Anyway, that is a general lifetime issue, not very signal/slot-specific.
Alternatives: Use a value class and send it via const reference. If MyClass can have subclasses, pass a const QSharedPointer&
About deleteLater: deleteLater() doesn't help here. It would make queued connections any safer, and for direct connections it makes no difference. The one use where deleteLater() comes into play is if the receiver needs to delete the sender. Then one should always use deleteLater(), so the sender can complete what he was doing, which would otherwise crash.
In a word (alright, function name) - deleteLater() :) All QObjects have it. It will mark the object for deletion, and this will then happen on the next event loop update.