Qt: «new with delete» вызывает утечки памяти с элементами управления? - PullRequest
16 голосов
/ 30 октября 2009

Я смотрел на пример 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 внутренне "удаляет" эти переменные-члены, когда он выходит из области видимости?

Ответы [ 4 ]

27 голосов
/ 30 октября 2009

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

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

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

7 голосов
/ 30 октября 2009

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

QHBoxLayout *buttonLayout = new QHBoxLayout();  // Memory leak?
//make sure you don't throw here
buttonLayout->addWidget(sendButton);
5 голосов
/ 30 октября 2009

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

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

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

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

0 голосов
/ 01 марта 2012

Не удаляется дважды из-за вызова .release ().

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

...