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

前端 未结 5 2118
有刺的猬
有刺的猬 2020-12-31 17:43

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

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


        
相关标签:
5条回答
  • 2020-12-31 18:19

    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.

    0 讨论(0)
  • 2020-12-31 18:19

    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.

    0 讨论(0)
  • 2020-12-31 18:25

    Main reason - possibility of dynamic creating / removing widgets. QObject (and QWidget) desing as classes that could not have copy constructor, so you couldn't pass is in arguments (by value/reference). So using pointers in all cases makes code more simple and clear.

    0 讨论(0)
  • 2020-12-31 18:34

    Allocating a widget as a local variable typically is not a good idea, since usually it will go out of scope before being useful in any way; since QObject supports the composition pattern via its "parent-child" relationships (that are well integrated with C++ destructors), usually the simplest thing is just to exploit such a feature.

    On the other hand, you can make it a member of your MainWindow class, or in general allocate it in any way such that it has a lifetime less than the lifetime of its parent. In facts, when such QLabel is destroyed, it automatically deregisters from its parent, avoiding double deallocation. But often is more comfortable just to allocate the widgets on the heap, registering them as children of the current window, since usually you don't actually need to access many widgets after you created them (e.g. labels), so it's not necessary to clutter your class with useless data members. You just do new QLabel(this, ...) into your window constructor and that's it.

    What you should not do, instead, is to allocate your widgets without new if their lifetime gets longer than the lifetime of their parent (e.g. putting them in a global or static variable) - doing this will cause the parent to try to delete them on its destruction, which will cause a crash at best, silent memory corruption at worst. This can be fixed (by manually deregistering the widgets in your class destructor), but I can't imagine any scenario where such a thing would be useful.

    0 讨论(0)
  • 2020-12-31 18:39

    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++".

    0 讨论(0)
提交回复
热议问题