Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is QObject destroyed signal called AFTER the destruction?

Tags:

c++

destructor

qt

Consider this test case:

class MyObject : public QObject
{
    Q_OBJECT
public:
    MyObject() { qDebug() << "MyObject constructor"; }
    virtual ~MyObject() { qDebug() << "MyObject destructor"; }
};

class Tracker : public QObject
{
    Q_OBJECT
public:
    Tracker() {}

public slots:
    void onDestructor() { qDebug() << "About to be destroyed!"; }
};

int main(int argc, char** argv)
{
    QCoreApplication app(argc, argv);

    Tracker tracker;

    MyObject *obj = new MyObject();
    QObject::connect(obj, SIGNAL(destroyed()), &tracker, SLOT(onDestructor()));
    delete obj;

    return app.exec();
}

It prints this:

MyObject constructor
MyObject destructor
About to be destroyed!

This behaviour contradicts the Qt documentation: "This signal is emitted immediately before the object obj is destroyed, and can not be blocked." Why does this happen?

like image 289
lamefun Avatar asked Dec 30 '11 19:12

lamefun


1 Answers

If you think about how the signal would get emitted, it's done by the base QObject - that's how the QObject knows it's being destroyed.

So when the derived class is destroyed, the most derived destructor gets run first (per standard C++ dtor handling), and the "MyObject destructor" message is displayed. When that dtor completes, the base dtors get run and in this case that's the QObject dtor, which then emits the signal and the "About to be destroyed!" message is displayed.

The wording in the docs you mentioned might be a bit imprecise. It might be better worded with something like, "This signal is emitted as the object obj is destroyed" or "This signal is emitted immediately before the object obj is completely destroyed".

like image 128
Michael Burr Avatar answered Nov 11 '22 23:11

Michael Burr