[SOLVED] WA_DeleteOnClose also ok for derived subclasses' destructor?



  • Hi,

    I have a class Dialog (derived from QDialog "as usual") and set the attribute Qt::WA_DeleteOnClose on it.

    @
    #ifndef DIALOG_H
    #define DIALOG_H

    #include <QDialog>
    #include <iostream>

    class Dialog : public QDialog {
    Q_OBJECT
    public:
    Dialog() {
    setAttribute(Qt::WA_DeleteOnClose);
    }

    ~Dialog() { /* not virtual!! (for real production code, please set this virtual!) */
    std::cout << "Destructor of Dialog" << std::endl;
    }
    };

    #endif
    @

    Then I have a derived class
    @
    #ifndef DERIVDIALOG_H
    #define DERIVDIALOG_H

    #include <iostream>
    #include "dialog.h"

    class DerivDialog : public Dialog {
    public:
    using Dialog::Dialog;
    ~DerivDialog() { std::cout << "Destructor of DerivDialog" << std::endl; }
    };

    #endif
    @
    which derives from the first class Dialog, above.

    main.cpp is as follows:
    @
    #include <QApplication>
    #include "derivdialog.h"

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);
    DerivDialog *dialog = new DerivDialog; // note free-store (i.e. heap!)
    dialog->show();
    return app.exec();

    // no delete of dialog
    }
    @

    Why is it, that closing the dialog actually calls Destructor of DerivDialog?? I mean: the destructor of the base class is not even virtual.
    I'd expect only the destructor of the Base class to be called? Why are both destructors called?
    (...actually this is good, since it is safe. But how does it work? Is it really safe?)

    main.cpp will print the following:
    Destructor of DerivDialog
    Destructor of Dialog

    Thanks for explanations.



  • ~Dialog() { /* not virtual!! (for real production code, please set this virtual!) */

    above comment is wrong.
    It is virtual cause one of it ancestors (QObject from the top of my head)
    has virtual destructor ( C++ standard ).

    Even though I prefer to put 'virtual' explicitly it is not needed.



  • I addition to the previous post, You are creating the object of derived class. Order of execution is derived class destructor and then base class destructor. This ensures that base class is stuff is also cleared up. I feel you can refer some tutorial on how the constructor and destructor gets called in case of inheritance.



  • --> Dheerendra

    Just be careful... we really do need virtual (somewhere up the class hierarchy, as alex_malyu has stated). Otherwise:

    @
    #include <iostream>

    class Base {
    public:
    Base() { std::cout << "Base constructor" << std::endl; }
    /* must put virtual here!!! */ ~Base() { std::cout << "Base destructor" << std::endl; }
    };

    class Deriv : public Base {
    public:
    Deriv() { std::cout << "Deriv constructor" << std::endl; }
    ~Deriv() { std::cout << "Deriv destructor" << std::endl; }
    };

    int main()
    {
    Base *b = new Deriv;
    delete b;
    return 0;
    }
    @

    --> alex_malyu

    Thanks perfect! This is the explanation/solution!!

    Indeed ~/Qt/5.4/gcc_64/include/QtCore/qobject.h has
    @
    class Q_CORE_EXPORT QObject
    {
    Q_OBJECT
    Q_PROPERTY(QString objectName READ objectName WRITE setObjectName NOTIFY objectNameChanged)
    Q_DECLARE_PRIVATE(QObject)

    public:
    Q_INVOKABLE explicit QObject(QObject parent=0);
    virtual ~QObject(); /
    !!! */
    @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.