Подтвердить что ты не робот

Qt: "новый без удаления" вызывает утечку памяти с элементами управления?

Я смотрел пример Qt здесь:

и внутри конструктора они имеют:

 Window::Window()
 {
     editor = new QTextEdit();   // Memory leak?
     QPushButton *sendButton = new QPushButton(tr("&Send message")); // Memory leak?

     connect(sendButton, SIGNAL(clicked()), this, SLOT(sendMessage()));

     QHBoxLayout *buttonLayout = new QHBoxLayout();  // Memory leak?
     buttonLayout->addStretch();
     buttonLayout->addWidget(sendButton);
     buttonLayout->addStretch();

     QVBoxLayout *layout = new QVBoxLayout(this);    // Memory leak?
     layout->addWidget(editor);
     layout->addLayout(buttonLayout);

     setWindowTitle(tr("Custom Type Sending"));
 }

Эти строки с комментариями

// Memory leak?

- это не те утечки памяти?

Если это так, поскольку класс Window не имеет конструктора, то я должен сделать все эти переменные (редактор уже есть) переменными члена Window?

Или.. Qt внутренне "удаляет" эти переменные-члены, когда выходит из области видимости?

4b9b3361

Ответ 1

Нет, функция addWidget() сохраняет владельца виджета. Затем он уничтожит виджеты, которыми он владеет.

Кроме того, вы можете читать здесь, что:

Как и в QObjects, QWidgets может быть создан с родительскими объектами указать право собственности, гарантируя, что объекты будут удалены, если они не будут дольше используется. С виджетами эти отношения между родителями и дочерними дополнительное значение: каждый дочерний виджет отображается на экране область, занимаемая его родительским виджетами. Это означает, что когда вы удаляете виджет окна, все дочерние виджеты, которые он содержит, также удаляются.

Ответ 2

Если существует исключение, созданное между new и addWidget, тогда да есть утечка памяти. В противном случае родительский элемент управления будет владеть памятью.

QHBoxLayout *buttonLayout = new QHBoxLayout();  // Memory leak?
//make sure you don't throw here
buttonLayout->addWidget(sendButton);

Ответ 3

В дополнение к правильному ответу Klaim:

Я бы сохранил эти указатели в std::auto_ptr, пока вы передаете их родителям.

std::auto_ptr<QHBoxLayout> buttonLayout( new QHBoxLayout() );
// make things which could throw...
layout->addLayout(buttonLayout.release());

Таким образом, вы уверены, что не имеете утечек.

Ответ 4

Он не будет удален дважды из-за вызова .release().

Примечание. std:: unique_ptr заменяет std:: auto_ptr. Надеюсь, QT будет поддерживать семантику перемещения, тогда release() будет вместо layout- > addLayout (std:: move (buttonLayout)), и без вызова для перемещения вы получите ошибку компиляции.