Я имел в виду, что он не может себя гарантированно отключить в своём деструкторе, а значит он должен либо подписываться на сигнал, который ему сообщит о том, что его хотят удалить, либо делегировать отписывание своему владельцу.
Сейчас, однако, я нашёл способ отписать объект не когда владелец захочет, а когда потеряется последняя владеющая ссылка на объект.
Для этого нужно использовать QSharedPointer с пользовательским deleter'ом.
Да, я как раз нашёл это в коде. Деструктор QObject действительно чистит очередь потока, в отличие от метода QObject::disconnect, который и ввёл меня в заблуждение.
Безопасное удаление через deleteLater может быть только в том случае, если этот метод каким-то образом гарантирует, что ни один асинхронный обработчик (в том числе, те, которые были вызваны после deleteLater!) не попадёт в очередь потока после удаления объекта. Пока я не вижу ничего об этом ни в документации, ни в коде.
Чуть позже почитаю код Qt более внимательно, и скажу, что я думаю по этому поводу.
Правильно, но это работает только тогда когда и владелец сигнала, и владелец слота принадлежат одному потоку. Это почти всегда верно в UI, и совсем не всегда верно в остальных частях проекта.
"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."
Сейчас, однако, я нашёл способ отписать объект не когда владелец захочет, а когда потеряется последняя владеющая ссылка на объект.
Для этого нужно использовать QSharedPointer с пользовательским deleter'ом.
http://doc.qt.io/qt-4.8/qsharedpointer.html#QSharedPointer-3
Статью поправлю, спасибо.
Сейчас исправлю в статье.
Чуть позже почитаю код Qt более внимательно, и скажу, что я думаю по этому поводу.
"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."
http://doc.qt.io/qt-5/qobject.html#dtor.QObject