Re[2]: Про QObject::deleteLater()
От: m2user  
Дата: 10.10.25 15:28
Оценка:
SaZ>Там уже почти на все вопросы ответили. Добавлю про объекты на стеке. Если вы объекту на стеке сделаете setParent и удалите его нового родителя, то будет как минимум двойной вызов деструктора со всеми вытекающими последствиями. А так, в целом, всё будет ок.

В иерархии parent-child я пока не углублялся, но буду иметь в виду.
В контексте слотов/сигналов получается, что объекты на стеке (локальные переменные функции или метода) вообще применять не следует, если создается connection c объектом, у которого время жизни более длительное.
И как тогда быть с RAII?

Вот тут (https://forum.qt.io/post/776397) предлагают QSharedPointer с deleteLater в качестве deleter. Насколько это годной подход?

SaZ>И если в слоте вы дёрнете sender() для объекта который помечен через deleteLater или находится в состоянии удаления, то qobject_cast<ВашТип> вернёт nullptr. Мне как-то раз понадобилось определять, удаляется ли сейчас объект или нет и я нашёл такой вот способ.


Но ведь этот способ ограничено применим: объект может быть не в состоянии удаления на момент проверки, но стать таковым после нее.

Возможно я не совсем правильно понимаю Warning из документации:

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.


В ней говорится про delete объекта принимающего события.
Является ли delete объекта генерирующего события проблемным и если да, то в какой степени (cause a crash и т.д)

SaZ>Ещё один неочевидный нюанс — это принадлежность к потокам. Если у вас объекты в общей иерархии памяти (родитель-ребёнок), то они всегда будут принадлежать одному потоку. И поменять принадлежность для всей иерахии можно только через корневой элемент. И да, делать moveToThread для объекта на стеке — тоже большой риск выстрелить себе в ногу. Надо очень хорошо будет следить за временем жизни объектов.


Про thread affinity.

Из документации не совсем ясно, почему выбран подход с привязкой объекта именно к потоку выполнения.

Иными словами я могу представить, что объект не является thread safe, т.е. обращение к нему должно быть только последовательными (сериализованными). И должна быть некая очередь вызовов.
Одна на объект или группу объектов. По идее эти вызовы могут выполняться на произвольном потоке (например из некоего thread pool`а).
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.