Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

destructors in Qt4

I'm very confused about using destructors in Qt4 and hope, you guys can help me.
When I have a method like this (with "Des" is a class):

void Widget::create() {
    Des *test = new Des;
    test->show();
}

how can I make sure that this widget is going to be deleted after it was closed?

And in class "Des" i have this:

Des::Des()
{
    QPushButton *push = new QPushButton("neu");
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(push);
    setLayout(layout);
}

where and how do I have to delete *push and *layout? what should be in the destructor Des::~Des() ?

like image 926
Berschi Avatar asked Sep 17 '09 05:09

Berschi


1 Answers

Qt uses what they call object trees and it's a bit different from the typical RAII approach.

The QObject class constructor takes a pointer to a parent QObject. When that parent QObject is destructed, its children will be destroyed as well. This is a pretty prevalent pattern throughout Qt's classes and you'll notice a lot of constructors accept a *parent parameter.

If you look at some of the Qt example programs you'll find that they actually construct most Qt objects on the heap and take advantage of this object tree to handle destruction. I personally found this strategy useful as well, as GUI objects can have peculiar lifetimes.

Qt provides no additional guarantees beyond standard C++ if you're not using QObject or a subclass of QObject (such as QWidget).


In your particular example there's no guarantee that anything gets deleted.

You'll want something like this for Des (assuming Des is a subclass of QWidget):

class Des : public QWidget
{
    Q_OBJECT

public:
    Des(QWidget* parent)
    : QWidget(parent)
    {
        QPushButton* push = new QPushButton("neu");
        QHBoxLayout* layout = new QHBoxLayout(this);
        layout->addWidget(push); // this re-parents push so layout 
                                 // is the parent of push
        setLayout(layout);
    }

    ~Des()
    {
        // empty, since when Des is destroyed, all its children (in Qt terms)
        // will be destroyed as well
    }
}

And you'd use class Des like so:

int someFunction()
{
    // on the heap
    Des* test = new Des(parent); // where parent is a QWidget*
    test->show();
    ...
    // test will be destroyed when its parent is destroyed

    // or on the stack
    Des foo(0);
    foo.show();
    ...
    // foo will fall out of scope and get deleted
}
like image 96
richardwb Avatar answered Nov 15 '22 22:11

richardwb