Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I have to delete these pointers?

Tags:

c++

qt

This is the MainWindow class which I call and use the function show() to make it visible to the user.

class MainWindow : public QMainWindow
{
    Q_OBJECT

    QWidget *centralWidget;
    QGridLayout* gridLayout;
    QGridLayout* infoBoxLayout;
    QHBoxLayout* buttonGroup;
    QHBoxLayout* subCategoryLayout;
    //... more widgets

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

    void setupUi();
    void setupConnections();

private slots:
    void add();
    void edit();
    void remove();
    void find();
    void clearAll();
    void screenshotDesktop();
    void screenshotApp();

    void currentSubCategoryChanged( const QString& );
    void curretCategoryChanged( const int );

    void keyPressEvent( QKeyEvent * );

};

I created for each widget (those pointers after the macro Q_OBJECT) a new object on the heap with new. However, I did not delete them anywhere in the program. Does this cause a memory leak in Qt? Or does something from Qt delete them automatically when destroying the class?

like image 400
Davlog Avatar asked Sep 26 '13 14:09

Davlog


3 Answers

If a widget has a parent set, then Qt will handle deleting the widget. In the case of a MainWindow, when you close it, the MainWindow and its children will be cleaned up, so pass the parent to the widget's constructor: -

QHBoxLayout* buttonGroup = new QHBoxLayout(this); // where this is the parent (MainWindow)

If you create a Widget such as this: -

QHBoxLayout* buttonGroup = new QHBoxLayout;

And haven't passed in the parent, then it will not be cleaned up and you'll have to handle that yourself.

like image 97
TheDarkKnight Avatar answered Sep 29 '22 15:09

TheDarkKnight


if you add them to the gui hierarchy then they will be cleaned up when the MainWindow is deleted

this is because parents assume ownership over their children (which is set with the various adds of the gui)

so a this->add(centralWidget); will call centralWidget->setParent(this); which will let centralWidget be deleted when MainWindow is deleted

you are free to delete QObjects yourself but beware dangling pointers (QPointer will help here). though I suggest using deleteLater() to ensure no strange behavior when a pointer still lives on the stack.

for more info about the object tree see here

like image 38
ratchet freak Avatar answered Sep 29 '22 16:09

ratchet freak


The automatic memory management through parent-child relationships is done by the QObject. QWidget happens to be a QObject, and it so happens that widgets that have parent widgets have the same underlying QObjects as parents.

A QObject with children automatically deletes its children in its destructor.

A QObject or a QWidget may be adopted by another object. For example, adding widgets to a layout will automatically reparent them to the widget the layout is set on. Even if a layout doesn't have a widget set on it yet, the reparenting will be done at the time you add the layout to a widget (or to a layout that has a widget set). It's pretty clever and saves a lot of typing and reduces possibilities for mistakes.

The idiomatic, minimum-typing way of adding widgets to another widget is:

MyWidget() {
  QLayout * layout = new QHBoxLayout(this); // set a layout on this widget
  layout->addWidget(new QLabel("foo")); // the label is reparented to this
  layout->addWidget(new QPushButton("bar")); // the button is reparented to this
}
like image 25
Kuba hasn't forgotten Monica Avatar answered Sep 29 '22 14:09

Kuba hasn't forgotten Monica