PDA

View Full Version : QObjects as data members stored by value



Radagast
6th August 2009, 14:30
In all Qt examples QObjects are stored in their parent by pointer and created on heap in the constructor:

class MainWidget: public QWidget
{
Q_OBJECT
QLabel* nameLbl;
QPushButton* fireBtn;
//etc
};

//in cpp:

MainWidget::MainWidget(QWidget* parent)
:QWidget(parent)
{
nameLbl = new QLabel(this)
fireBtn = new QPushButton("Fire", this);
//etc
}

Futhermore, Trolls recommend to create QObjects usually on heap, except in main() function and dealing with modal dialogs like QColorDialog.
But there can be another approach. If we know exactly that the lifetime of a child is the same, as its parent, and the parent and thread of a child will never change, we can write this:

class MainWidget: public QWidget
{
Q_OBJECT
QLabel nameLbl;
QPushButton fireBtn;
//etc
};

//in cpp:

MainWidget::MainWidget(QWidget* parent)
:QWidget(parent),
nameLbl(this),
fireBtn("Fire", this)
{

}

pros:
1. Less typing (using dots . instead of arrows -> , laconic constructing)
2. Less calls to 'new' and 'delete', that are always expensive.
any cons? are there any drawbacks of this approach? do you use such approach?
The only one that I know is that you need to be accurate when connecting to signals that are emitted when a child object destroys (QObject::destroyed etc). Let's assume that we're not interested in such signals.

caduel
6th August 2009, 18:37
passing this as the owner of your stack based nameLbl etc will cause it to be a child (it the Qt object parent sense) of "this". When this is destroyed it will destroy its children (with delete).
delete must not be called on stack objects but only on stuff allocated with new. So your code will crash.

If you do that, you must make sure that all stack objects are not owned by any other objects.

HTH

Radagast
6th August 2009, 18:53
It won't crash, because the desctructors of data members are called BEFORE the destructor of the base class.

caduel
6th August 2009, 19:14
yes, you are right :)
in that case it should work