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:
const
reference then, depending on your connection type, QT will pass the value of the object for you (see this for some details) 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.