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