QPointer и удаление объектов

У меня есть приложение Qt, которое использует QPointers для вызова новых диалогов пользовательского интерфейса (виджетов). В основном приложении может быть несколько одинаковых виджетов с разными данными. У меня проблема в удалении и освобождении памяти для каждого виджета. Если я отслеживаю использование ОЗУ программой, каждый раз, когда я нажимаю кнопку, чтобы открыть один из этих новых виджетов, он увеличивает объем оперативной памяти, а когда я закрываю виджет, кажется, что он не освобождает оперативную память. Я пытался использовать deleteLater и другие решения, но программа продолжает сбоить.

Некоторый пример кода здесь:

QPointer<ListReservations> listResWindow = new ListReservations(resID);
listResWindow->setNum(numpeople);
listResWindow->show();

Это вызовет виджет "ListReservations", который объявлен как QDialog (НЕ модальный). В этом диалоговом окне у меня есть кнопка, чтобы закрыть окно, которое вызывает слот QWidget::close().

Я предполагаю, что вопрос в том, как моя основная программа (с QPointer) узнает, когда диалог закрыт, а затем освобождает диалог и (если возможно) удаляет указатель, чтобы сэкономить еще больше памяти...

Я думал, что вы могли бы сделать QConnect() для объекта QPointer, но я не могу найти какие-либо сигналы или слоты, которые позволили бы передать указатель, не говоря уже о отправке сигнала, когда диалог действительно закрыт и готов к удаление.

Может быть, мне нужна какая-то функция в основной программе, которая принимает общий объект-указатель, а затем вызывает QDialog перед вызовом собственного закрытого слота? В этой функции он передал бы себя на уничтожение? Просто выбрасываю идеи, которые я пытался реализовать, но потерпел неудачу....

Я не думаю, что смогу повторно использовать один и тот же указатель в другом месте, потому что теоретически у вас может быть несколько открытых окон ListReservations одновременно.


person Rob S    schedule 03.03.2010    source источник


Ответы (1)


Убедитесь, что вы установили флаг атрибута Qt::WA_DeleteOnClose в своем диалоговом окне, используя QWidget::setAttribute(). Это должно гарантировать, что диалоговое окно правильно уничтожается при его закрытии. Дополнительную информацию см. в документации Qt.

Предполагая, что память теперь правильно освобождена, указатель должен стать недействительным, согласно документации Qt. :

Защищенный указатель, QPointer, ведет себя как обычный указатель C++ T *, за исключением того, что он автоматически устанавливается в 0, когда объект, на который указывает ссылка, уничтожается (в отличие от обычных указателей C++, которые в таких случаях становятся «висячими указателями»).

person Ton van den Heuvel    schedule 03.03.2010
comment
Ваш первый совет по удалению при закрытии точен. Однако объекты QPointer будут автоматически установлены в NULL, когда объект, на который он указывает, будет удален, поэтому не должно быть необходимости в слоте onDialogClosed (это я вижу). - person Caleb Huitt - cjhuitt; 03.03.2010
comment
Я никогда раньше не использовал QPointer и предполагал, что у него нет такого поведения, спасибо за информацию. Я обновлю ответ. - person Ton van den Heuvel; 03.03.2010
comment
Я также должен добавить, что существуют потенциальные условия гонки при использовании QPointer для объекта, принадлежащего другому потоку. В этом случае объект может быть удален без установки объекта QPointer в 0. - person Caleb Huitt - cjhuitt; 04.03.2010