PDA

View Full Version : Allocating widgets on the stack verses using the heap



Ronayn
4th August 2011, 20:10
I am just curious if there are any gotcha's to creating widgets on the stack? In the QT examples I've looked at, typically the main function looks like this:

int main(int argc, char** argv)
{
QApplication app(argc, argv);
MainWindow mw(0, "mainwindow");

if (mw.Initialize())
{
app.setMainWidget(&mw);
mw.show();
return app.exec();
}

return 0;
}


Here, the instance of my MainWindow is created on the stack. However, the widgets that make up the MainWindow are all allocated on the heap using new. A typical header looks something like this:

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
MainWindow(QWidget* pParent=0, const char* pInternalName=0, WFlags Flags=WType_TopLevel);
~MainWindow();

private:
QMenuBar* mp_MenuBar;
QWidget* mp_CentralWidget;
QVGroupBox* mp_ControlPane;
StatusPane* mp_StatusPane;
...


You can see that pointers to widgets are used in the header -- but why? If the MainWindow widget is going to create a static display, why not declare them as actuals objects and simply construct them in the initializer list for the MainWindow constructor?

squidge
4th August 2011, 22:03
Its fine to create objects on the stack as long as you know that the lifetime of the object will be less than the lifetime of that particular stack frame.

For example, the main call is not terminated until app.exec returns, therefore it is safe to create objects on the stack here.

This is not always the case, so for automated tools such as QtDesigner/UIC, it is safer to always create them on the heap.

wysota
4th August 2011, 22:32
And a general rule of a thumb is to always create objects with a parent on the heap and not on the stack.

Santosh Reddy
5th August 2011, 00:14
You might be aware of the fact creating on the stack will limit the scope of the object to the block in with it is declared, and objects on heap will have a global scope.

There is one more use if object is declared in heap (I mean as a pointer), it is dynamic is nature, now here dynamic here refers not only to the memory being allocated but also to the object itself, i.e. the object it self can be changed dynamically with another object / derived custom object.

If you see at the example of QMainWindow (as you pointed out), even through is created on stack, it internally has pointers, such that mainwindow internal widgets can be are created on heap. Now here the internal objects could also have been create on the stack as member objects, but that it is design / requirement of QMainWindow.

As an example, it is required for the QMainWindow to have an ability to change the centralWidget at runtime, so to support the feature of changing the centralWidget, mp_CentralWidget pointer is used. Well you can still use the mp_CentralWidget pointer of QMainWindow to point to a widget created on the stack.

Try this, create a QMainWindow on stack, and also any other widget on stack, and set this widget as the centralWidget of the MainWindow, the internal pointer of the mainwindow will now point to the widget which is on stack.


You can see that pointers to widgets are used in the header -- but why? If the MainWindow widget is going to create a static display, why not declare them as actuals objects and simply construct them in the initializer list for the MainWindow constructor?
As I explained above, pointers to widgets are used to support the ability to change the widget dynamically, if created as member objects, they cannot to replaced with user defined widgets.

So to conclude, I would say, pointers are used internally in QMainWinodow in order to give dynamic features, but not as an intention to create widgets on heap.