58

Does Qt automatically remove connections between objects , when one of the side is deleted ?

e.g connect (A .. , B ..) , when A (a pointer) is deleted , or B is deleted , will the connection be disconnected ?

Is it necessary to use disconnect explicitly in destructor ?

user35443
  • 6,309
  • 12
  • 52
  • 75
daisy
  • 22,498
  • 29
  • 129
  • 265

1 Answers1

58

Yes, the QObject::~QObject destructor takes care of that:

All signals to and from the object are automatically disconnected, and any pending posted events for the object are removed from the event queue.
However, it is often safer to use deleteLater() rather than deleting a QObject subclass directly.

Do take care though:

Warning: Deleting a QObject while pending events are waiting to be delivered can cause a crash. You must not delete the QObject directly if it exists in a different thread than the one currently executing. Use deleteLater() instead, which will cause the event loop to delete the object after all pending events have been delivered to it.

Mat
  • 202,337
  • 40
  • 393
  • 406
  • Also note this: "Warning: Deleting a QObject while pending events are waiting to be delivered can cause a crash." Use [`deleteLater()`](http://qt-project.org/doc/qt-4.8/qobject.html#deleteLater) if this situation might occur. –  May 13 '12 at 10:04
  • 10
    also be careful with lambdas (if you use any) in the deleted object: they are NOT disconnected... guess how I know ;) – mBardos Aug 04 '15 at 14:29
  • This is true in Qt5 as well. – RegularlyScheduledProgramming May 23 '16 at 21:04
  • 6
    @mBardos since Qt 5.2 there is an overload that takes a context object. The connection to the lambda will be disconnected when the context object is deleted. – Zitrax Aug 10 '17 at 14:28
  • @RegularlyScheduledProgramming I am still on 5.1.1, but I can say one thing: it was needed! ;) – mBardos Aug 11 '17 at 07:08
  • Are connections also disconnected from objects to the deleted object, if the from-objects live in other threads? – Johannes Schaub - litb May 14 '19 at 18:55
  • @JohannesSchaub-litb: I believe they are, but haven't done any Qt in the past few years so I'm rusty. `deleteLater` certainly preferred, and required if you're deleting an object that is owned by another thread (indicated in the docs). – Mat May 15 '19 at 07:56
  • 1
    @JohannesSchaub-litb, most likely NOT. I am able to detect some crashes with the use of Valgrind. If an object is marked for `deleteLater()` and before it gets executed, if any new signal is queued from another thread, then that leads to undefined behaviour. Depending on the OS, it crashes sometimes at random places. Hard to track bugs. :-( – iammilind Jul 20 '19 at 17:03
  • @iammi I think that you might get the crash from something else. Qt does define that scenario in the manual. queued signals and deleteLater both are events, which are erased properly if you delete the object from the correct thread. Perhaps your deleteLater calls are done on already dead object. – Johannes Schaub - litb Jul 20 '19 at 19:13
  • @JohannesSchaub-litb, I am using `unique_ptr` with custom deleter as `deleteLater`, so it's assured that the object deletion is done properly. There is no error with valgrind either (viz double free). Qt says that the pending signals before `deleteLater()` are entertained. But imagine a case, where the signal is emitted on an object after `deleteLater()` is marked. In such case, the `deleteLater()` will get invoked first followed by that signal. This results in UB. Anyhow, currently I am debugging an issue, where the Qt lib is causing some memory issues consistently. There are some bugs in Qt. – iammilind Jul 20 '19 at 19:30
  • @iamm emitted "on" the deleted object as in "emit Foo()" and Foo belongs to the deleted object? Of course that is undefined behavior. Otherwise, emission on another object will never call a slot of a deleted object with QueuedConnection, if that object was deleteLater-ed and the deleteLater was already processed. – Johannes Schaub - litb Jul 20 '19 at 19:42
  • Of course, if you do a DirectConnection, then the moment the slot is invoked in the other thread, deleteLater races with that slot's member accesses and undefined behavior arises. Delete can then happen anytime in the objects' own thread. – Johannes Schaub - litb Jul 20 '19 at 19:44