| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Удаление QObject: автоматически или нет |
| Автор: sustenuto 29.5.2011, 19:26 | ||
| Здравствуйте! Я первый раз работаю с QT и столкнулся с проблемой, решение которой не смог найти в документации. Суть сводиться к тому, что не ясно, кто должен удалять объект, производный от QObject: я или библиотека QT. Оказывается, что оба случая работают неправильно: если я создаю объект как статическую переменную (которая удаляется автоматически во время завершения программы), либо если я создаю его динамически, оператором new, и не удаляю совсем. В первом случае я получаю Segmentation Fault, во втором — утечку памяти. Мой класс описан примерно вот так:
Если объект LoadFileDialog сделать статической переменной, то при работе во время вызова его деструктора происходит Segmentation Fault. Если я объект не удаляю, то деструктор не вызывается вообще! Это я вижу, поскольку надписи "DIALOG DESTROYED!!!!" нет. Я предположил, что объект всё-таки уничтожается, но в силу того, что деструкторы QDialog и QWidget НЕ ВИРТУАЛЬНЫ (в отличие от деструктора QObject), вызывается неправильный деструктор. Друзья, как правильно делать? PS. Кстати, если у меня ещё что-нибудь неправильно в классе, скажите плиз. Буду благодарен) |
| Автор: sustenuto 29.5.2011, 19:42 | ||||||||
borisbn, спасибо за ответ!
На самом деле, не совсем так. То есть если вызывается `delete dialog' где dialog имеет тип QDialog* (и фактически является объектом LoadFileDialog), то вызовется ~QDialog(). При этом `delete (QObject*)dialog' вызовет ~LoadFileDialog(). Я так понимаю.
Вроде бы максимально упростил код, ошибка сохраняется: 1. Статически. После закрытия окна получаю Segmentation Fault
2. Динамически. Деструктор ~LoadFileDialog() никогда не вызывается
|
| Автор: kosmonaFFFt 30.5.2011, 05:40 | ||
А попробуй создавать не статически, а просто
|
| Автор: math64 30.5.2011, 07:42 | ||||
Когда ты создаёшь переменную так:
вместе с переменной dlg создаётся булевская переменная, по которой проверяется, создавался ли объект dlg. При первом вызове main() он будет создан. Деструктор dlg будет вызван перед завершением программы, т.е. после выхода из main(), перед которым был вызван деструктор app, что и вызывает ошибку. Нужно объявлять так:
В этом случае деструкторы будут вызывааться при выходе из main() в порядке, обратном объявлению. |
| Автор: sustenuto 30.5.2011, 14:03 | ||
Ага, спасибо! Только проблема в том, что объект надо создавать не в main, а в другой функции. Можно было бы делать QApplication app статическим, но у него нету конструктора по умолчанию((( Так что и этот вариант тоже не прокатывает( Решение проблемы я нашёл: создавать dialog динамически и затем выполнять
Тогда он удаляется корректно. Всем спасибо! |
| Автор: math64 30.5.2011, 14:35 | ||
Создай класс, производный от QApplication и сделай LoadFileDialog dlg; или LoadFileDialog* dlg; полем в этом классе. |
| Автор: sustenuto 2.6.2011, 18:20 | ||
Здорово, отличное и красивое решение! Спасибо |