Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ - Why do I create these widgets on the heap?

Tags:

c++

qt

When creating a GUI with C++ and Qt you can create a label for example like this :

QLabel* label = new QLabel("Hey you!", centralWidgetParent);

This creates the object on the heap and will stay there until I either delete it manually or the parent gets destroyed. My question now is why do I need a pointer for that? Why not create it on the stack?

//Create a member variable of Class MainWindow
QLabel label;

//Set parent to show it and give a text so the user can see it
    QWidget* centralWidget = new QWidget(this); //Needed to add widgets to the window
    this->setCentralWidget( centralWidget ); 
    label.setParent(centralWidget);
    label.setText( "Haha" );

This works fine, I can see the label and it did not vanish.

We use pointers in C++ to let something live longer so we can use an object in various scopes. But when I create a member variable, won't it stay until the object gets destroyed?

Edit: Maybe I didn't clarify it enough. This is the MainWindow class:

class MainWindow : public QMainWindow
{
    Q_OBJECT
    QLabel label; //First introduced here...

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
};

//Constructor
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QWidget* centralWidget = new QWidget(this);
    this->setCentralWidget( centralWidget );
    label.setParent(centralWidget);
    label.setText( "Haha" );
}
like image 958
Davlog Avatar asked Sep 24 '13 14:09

Davlog


3 Answers

If your label gets out of the scope, the destructor (QLabel::~QLabel) will be called. From the docs:

Destroys the object, deleting all its child objects.

It is not necessary to create object on the heap - you could put the object on the stack, but then you need to be responsible about lifetime of the object (the one of the most problematic issues about allocating data on the heap is the question of "who and when should delete these objects?", and in Qt it is handled by the hierarchy - whenever you delete your widget, all the child widgets will be deleted).

Why your program works - I don't know - it may just not work (label is destroyed at the end of the scope). Another issue is - how will you change the text of the label (from some slot, for example) if you don't have a reference to it?

Edit I just saw that your label is a member of the MainWindow. It is perfectly fine to have a complete objects, and not the pointer to the objects as the member of your class, as it will not be destroyed before MainWindow is. Please note that if you create instance of your MainWindow like this:

MainWindow *w = new MainWindow();

label will be created on the heap.

like image 71
Nemanja Boric Avatar answered Oct 26 '22 22:10

Nemanja Boric


Because that is how Qt was designed. I realize that's not a very satisfying answer, but Qt was simply designed as "widgets are created on the heap, and parents are responsible for deleting their children".

Realize that the origins of Qt are old, older than what we consider "modern C++".

like image 31
Sebastian Redl Avatar answered Oct 27 '22 00:10

Sebastian Redl


Another thing to keep in mind is that Qt uses the so called pimpl paradigm where object data is implicitly shared and managed behind the class you actually instantiate. See here: http://qt-project.org/wiki/Dpointer

The bottom line is that if you are allocating on the stack in order to avoid using the heap, Qt is just pulling a fast one on you and using the heap anyway.

like image 37
Thadeux Avatar answered Oct 27 '22 00:10

Thadeux