Delete vs deleteLater()
-
Hi,
for me it isn't clear if there is a difference using delete or the deleteLater() slot?void Class::create() { if (m_timer != nullptr) delete m_timer ; // <-- or m_timer->deleteLater() ? m_timer = new QTimer(); connect(m_timer , &QTimer::timeout, this, &Class::process); connect(this, &Class::destroyed, m_timer , &QTimer::deleteLater); // delete the member when the class is going to be destroyed }
Is there a advantage using deleteLater() in the if-clause?
Thanks !
-
If you have an event loop and no real memory cluttering then the suggestion is to use
deleteLater()
so you don't have to worry. If you usedelete
directly you must make sure that:- There are no pending events that
m_timer
should receive (in this case atimerEvent
) or it might crash - You must make sure
m_timer
lives in the same thread as the one you are callingdelete
from - You must make sure the method in which you call
delete
is not a slot triggerd by the object you are trying to delete or it might crash
Basically, life is too short to care about all the above and the performance improvement is negligible so using
deleteLater()
is just better in this caseP.S.
connect(this, &Class::destroyed, m_timer , &QTimer::deleteLater);
can be replaced by just passingthis
to theQTimer
's constructor - There are no pending events that
-
Hi,
for me it isn't clear if there is a difference using delete or the deleteLater() slot?void Class::create() { if (m_timer != nullptr) delete m_timer ; // <-- or m_timer->deleteLater() ? m_timer = new QTimer(); connect(m_timer , &QTimer::timeout, this, &Class::process); connect(this, &Class::destroyed, m_timer , &QTimer::deleteLater); // delete the member when the class is going to be destroyed }
Is there a advantage using deleteLater() in the if-clause?
Thanks !
@beecksche said in Delete vs deleteLater():
Is there a advantage using deleteLater() in the if-clause?
Depends on the use case.
If you expect that the pointer still receives some event in the current event loop iteration, or shortly after the current execution and want to "mark it as deleted" you use deleteLater()
Otherwise you can always call delete.Another example: if you want to delete a pointer, but still have to pass it to a base-class implementation to let this base class also finish its work you also must call deleteLater.
But basically if you are unsure try it with delete, if you encounter issues, try deleteLater. If there are still issues there is a bug/misconception in the code.
-
If you have an event loop and no real memory cluttering then the suggestion is to use
deleteLater()
so you don't have to worry. If you usedelete
directly you must make sure that:- There are no pending events that
m_timer
should receive (in this case atimerEvent
) or it might crash - You must make sure
m_timer
lives in the same thread as the one you are callingdelete
from - You must make sure the method in which you call
delete
is not a slot triggerd by the object you are trying to delete or it might crash
Basically, life is too short to care about all the above and the performance improvement is negligible so using
deleteLater()
is just better in this caseP.S.
connect(this, &Class::destroyed, m_timer , &QTimer::deleteLater);
can be replaced by just passingthis
to theQTimer
's constructorThanks for the replies and information. I will use the deleteLater() slot!
@VRonin :
P.S.
connect(this, &Class::destroyed, m_timer , &QTimer::deleteLater); can be replaced by just passing this to the QTimer's constructorMy class Class is moved to another thread and the create function is invoked (to create the members in thread1).
... class.moveToThread(&thread1); ... QMetaObject::invokeMethod(&class, "create", Qt::QueuedConnection); ...
So if I would use
m_timer = new QTimer(this);
this (Class object) isn't be created in thread1. And so the parent (this) is not allowed to delete the QTimer object (because it "lives" not in the same thread). Or do I misunderstood this?
- There are no pending events that
-
Thanks for the replies and information. I will use the deleteLater() slot!
@VRonin :
P.S.
connect(this, &Class::destroyed, m_timer , &QTimer::deleteLater); can be replaced by just passing this to the QTimer's constructorMy class Class is moved to another thread and the create function is invoked (to create the members in thread1).
... class.moveToThread(&thread1); ... QMetaObject::invokeMethod(&class, "create", Qt::QueuedConnection); ...
So if I would use
m_timer = new QTimer(this);
this (Class object) isn't be created in thread1. And so the parent (this) is not allowed to delete the QTimer object (because it "lives" not in the same thread). Or do I misunderstood this?
@beecksche said in Delete vs deleteLater():
Or do I misunderstood this?
if you move
class
to a second thread thenClass::create
should be called in the second thread andm_timer
can be made child ofclass
the problem is only if you give a parent that lives in another thread, this should not be the case.It's at least risky to have
class
on the stack and move it to the second thread as it might go out of scope and crash the thread that tries to use it. -
@beecksche said in Delete vs deleteLater():
Or do I misunderstood this?
if you move
class
to a second thread thenClass::create
should be called in the second thread andm_timer
can be made child ofclass
the problem is only if you give a parent that lives in another thread, this should not be the case.It's at least risky to have
class
on the stack and move it to the second thread as it might go out of scope and crash the thread that tries to use it. -
Which one? did you reimplement
run()
?As you can see
Worker *worker = new Worker;
which is the equivalent of yourclass
is not on the stack and, although the example doesn't show it,Worker
is free to have child objects