Re[5]: Про QObject::deleteLater()
От: Skorodum Россия  
Дата: 10.10.25 11:54
Оценка: +1
Здравствуйте, m2user, Вы писали:

M>Я к тому, что критерий проблемности "вызов delete из потока, отличного от того, в котором живёт объект" — неверный для объекта, который может быть emitter`ом с QtQueuedConnection.

M>Т.е. для таких объектов вызов delete из любого потока будет небезопасным.
Конечно же нет

QObject::~QObject()
All signals to and from the object are automatically disconnected, and any pending posted events for the object are removed from the event queue.


M>А что насчет событий, которые сгенерированы удаляемым объектом? deleteLater ждёт пока все подписчики их обработают?

Да, это же легко проверить:

#include <QObject>
#include <QDebug>
#include <QCoreApplication>
#include <QTimer>

class Object : public QObject
{
    Q_OBJECT
signals:
    void mySignal();
public:
    Object(QObject *parent = nullptr) : QObject(parent)
    {
        QTimer::singleShot(10, this, [this](){
            emit mySignal();
            deleteLater();
        });

        connect(this, &QObject::destroyed,  this, []{ qDebug() << "Object destroyed"; });
        connect(this, &Object::mySignal, this, []{ qDebug() << "Signal received"; });
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    const auto *obj = new Object(&app); // owned by app, but there is no double delete
    QObject::connect(obj, &QObject::destroyed, &app, &QCoreApplication::quit);
    return app.exec();
}

#include "main.moc"

Signal received
Object destroyed


Типичные случаи когда надо использовать deleteLater:
    1. Из слота самого объекта
    2. Между потоками (но обычно это признак пробленого дизайна)
    3. Асинхронные обработчики событий QNetworkReply
    4. QThread::finished -> deleteLater
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.