Название: Механизм parent'ов, деструкторов Отправлено: xk от Октябрь 19, 2007, 16:41 OS: win-xp
Qt: 4.3.2 Простая до тошноты программа вываливается при закрытии окна. Причем вываливается, судя по дебаггеру где-то внутри QToolBar. Сдается мне что я чего-то не понимаю в сабжевом механизме. Подскажите что может быть не так ? может на другой платформе/версии Qt всё нормально ? main.cpp Код: #include "app.h" app.h Код: #ifndef __GRADARAPP_H__ app.cpp Код: #include "app.h" guimanager.h Код: #include <QObject> guimanager.cpp Код: #include "guimanager.h" mainwin.h Код: #ifndef __MAINWIN_H__ mainwin.cpp Код: #include <QTextEdit> Название: Re: Механизм parent'ов, деструкторов Отправлено: Kainit от Октябрь 19, 2007, 17:36 так должно писать уважающему себя мужу (если конечно не хочется ликов и ошибок)
Код: CApp::~CApp() Надеюсь, причина ошибки понятна... Название: Re: Механизм parent'ов, деструкторов Отправлено: xk от Октябрь 19, 2007, 17:51 Вот как раз не понятна :)
Я ведь пишу Код: m_pGuiManager = new CGuiManager(this); Название: Re: Механизм parent'ов, деструкторов Отправлено: EhTemka от Октябрь 19, 2007, 18:15 Или я что-то недогоняю...
А как вообще у тебя происходит выход из процесса? exec(); вижу, а где quit(), или что-то в этом роде? Название: Re: Механизм parent'ов, деструкторов Отправлено: Kainit от Октябрь 19, 2007, 18:20 Цитировать exec(); вижу, а где quit(), или что-то в этом роде? Какой quit(), окститесь и поглядите самый первый пример Qt.Код: int main(int argc, char *argv[]) 2xk Предлагаю поставить брекпоинты и убедиться что все деструкторы вызываются вне зависимости от того, есть ли вставка Код: delete m_pGuiManager Разумеется, у QObject с наследованием и уничтожением потомков всё в порядке. А в чём причина неадекватного поведения? Точно сказать сложно, но причина именно в последовательности удаления и в том что в Qt по разному в двух случаях освобождает ресурсы связанные с MainWindow и с Application. А ошибка сама по себе забавная и я вижу такую впервые, поскольку всегда за собой удалял всё сам... Название: Re: Механизм parent'ов, деструкторов Отправлено: xk от Октябрь 19, 2007, 20:31 В обоих случаях деструкторы вызываются в нужном порядке.. только в варианте "new CGuiManager(this)", вылетает ошибка доступа к памяти.
Попробую троллям сейчас отослать... Название: Re: Механизм parent'ов, деструкторов Отправлено: Kainit от Октябрь 19, 2007, 21:35 Ты не понял мысли, хотя троллям ты отослать конечно можешь.
Я говорю не о порядке деструцирования твоих объектов app->pGuiManager->pMainWindow, я говорю о порядке деструцирования объектов данного приложения вообще. Если ты почитаешь исходники, или потыкаешь в проперти разных объектов (типа app, а точнее, в его список детей), то всё станет понятнее. Когда ты явно говоришь delete pGuiManager, то сначала разрушается pGuiManager и pMainWindow, а затем уже разрушаются вспомогательные объекты, созданные QApplication и потому всё завершается корректно. Когда же ты не вызываешь delete pGuiManager, то дети QApplication умирают в порядке создания, т.е., сначала всевозможные шрифтовые фабрики и т.п., а потом уже твои pGuiManager и pMainWindow (создал ты их позже и в список child-ов они попали в конец). Но по каким-то причинам, QMainWindow не знает о том что по сути весь контекст QApplication разрушился и твоя прога падает. Цитировать Попробую троллям сейчас отослать... Тролли посмеются.Название: Re: Механизм parent'ов, деструкторов Отправлено: Dodge от Октябрь 20, 2007, 01:20 Ужос... зачем наследоватццо от QApplication? о_0
Что вам простите там понадобилось, это не Qt'шный стиль! ...и вообще... лучше избежать наследования, если это возможно. Но и не это главное... QApplication этж синглтон - ядро вашей программы, сингл тон в полном порядке и багов за ним не значитццо... тк зачем к нему своито прекручивать... жжжесть... З.Ы. Аффтор, если не ошибаюсь, сам Страуструп( можт это был и Архангельской... ну не суть ) грозил пальчиком и говорил: ай-ай-ай... незя наследоватся без нужды... ай-ай-ай ;D Многие опытные программисты рекомендуют применять наследование в случаех с интерфейсом... неговоря уже а множественном наследовании... Ну это все лирика... к чему это все - ОСТАВЬ В ПОКОЕ QApplication! У него хоть диструктор и виртуальный... но лучше его не трогать. Посмотри как пишут сами троли. Загляни в экзамплы... я думаю проблемма исчезнет. Название: Re: Механизм parent'ов, деструкторов Отправлено: xk от Октябрь 20, 2007, 08:45 Да, с наследованием от QApplication - это я погорячился :)
Проблема решена, всем спасибо ! :) Название: Re: Механизм parent'ов, деструкторов Отправлено: Cyrax от Декабрь 19, 2007, 15:17 По поводу деструкторов и parent'ов: не закрывается дочернее окно при закрытии главного.
Имеется главное окно dep и дочернее tload, оба - наследники QMainWindow. Из главного окна создаю и отображаю дочернее окно: Цитировать tload = new tgLoad(this); Запускаю приложение, из главного окна открываю дочернее tload. Затем закрываю главное. При этом дочернее окно не закрывается, хотя в конструкторе tload'а в качестве родителя я указываю this, т.е. объект главного окна.tload->show(); Далее dDebug'ами проверяю последовательность вызова конструкторов и деструкторов. Получаю следующие результаты: 1. Открываю dep, открываю tload, закрываю tload, закрываю dep: Цитировать warning: dep constructor Последние 2 сообщения выводятся только при закрытии главного окна dep. Т.е. деструктор tload вызывается не при закрытии окна tload, а только при закрытии главного окна dep.warning: tload constructor warning: dep destructor warning: tload destructor Как по мне, должно быть так: Цитировать warning: dep constructor 2. Открываю dep, открываю tload, закрываю dep:warning: tload constructor warning: tload destructor warning: dep destructor Цитировать warning: dep constructor Та же самая последовательность вызовов, при этом при закрытии главного окна дочернее не закрывается.warning: tload constructor warning: dep destructor warning: tload destructor В данном случае должно быть так: Цитировать warning: dep constructor warning: tload constructor warning: tload destructor warning: dep destructor Если недопонимаю чего-то простого, просьба не РРРРРычать... Название: Re: Механизм parent'ов, деструкторов Отправлено: _govorilka от Декабрь 19, 2007, 15:46 Сделай вот так, и попробуй запустить...
Код: CGuiManager::~CGuiManager() В твоём случае, окно должно удалиться самостоятельно (это написано внутри библиотеки). Если хочешь удалять окна ручками, то надо писать вот так: Код: m_mуWindow->deleteLater(); Название: Re: Механизм parent'ов, деструкторов Отправлено: Вячеслав от Декабрь 19, 2007, 16:34 Вообще-то RTFM ;) При закрытии окно не удаляеться по-умолчанию,а скрываеться и прибиваеться парентом ;) Ставь флаг однако ....
setAttribute(Qt::WA_DeleteOnClose); Название: Re: Механизм parent'ов, деструкторов Отправлено: ритт от Декабрь 19, 2007, 17:33 а мне вот всё-рно хочется поРРРРРычать...
неделю-две назад только закрыли эту тему, где всё развёрнуто было оговорено и расжёвано уже 177 страниц форума - такие вопросы ну по-любому должны были проскакивать...но вот, лень же ж вам, люди, поиском-то воспользоваться?! Название: Re: Механизм parent'ов, деструкторов Отправлено: ритт от Декабрь 19, 2007, 18:04 а амароки отнаследовались от куаппликэйшена...чёрт...как я в них разочаровался
а ведь амарок был моим любимым плеером...теперь придётся выбросить! :( Название: Re: Механизм parent'ов, деструкторов Отправлено: Cyrax от Декабрь 19, 2007, 19:55 Всё понятно, спасибо.
Цитировать неделю-две назад только закрыли эту тему, где всё развёрнуто было оговорено и расжёвано http://prog.org.ru/forum/index.php/topic,6541.0.html ?Собственно, для того, чтобы при закрытии главного окна закрывались все дочерние и при этом не вываливалось ошибок, хотел вначале очистить свойство quitOnLastWindowClosed приложения (по умолчанию - установлено) + для главного окна установить свойство setAttribute(Qt::WA_DeleteOnClose, true) + законнектить "сигнал удаления главного" окна на слот quit() приложения. Поскольку у QMainWindow нет "сигнала удаления", придётся его генерировать вручную в деструкторе. Довольно муторно. Пока остановился на варианте, когда свойство quitOnLastWindowClosed оставляю установленным + перегружаю слот closeEvent() в главном окне: Цитировать void dep::closeEvent(QCloseEvent *event) В данном случае при закрытии главного окна вначале закрывается (hide'ится) дочернее окно (tload), затем - главное (dep). Далее срабатывает атрибут quitOnLastWindowClosed...{ this->tload->close(); QMainWindow::closeEvent(event); } Поправте, если что не так. Название: Re: Механизм parent'ов, деструкторов Отправлено: ритт от Декабрь 19, 2007, 20:30 > Поскольку у QMainWindow нет "сигнала удаления"...
QMainWindow не наследуется от QObect??? я в шоке! всегда думал, что наследуется... а что мешает ставить в конструкторе Qt::WA_DeleteOnClose, а в деструкторе делать клозе() дитёнку для надёжности? Название: Re: Механизм parent'ов, деструкторов Отправлено: Cyrax от Декабрь 19, 2007, 21:10 Цитировать а что мешает ставить в конструкторе Qt::WA_DeleteOnClose, а в деструкторе делать клозе() дитёнку для надёжности? Я так делал - вываливается runtime error (в режиме run).В главном окне в конструкторе устанавливаю атрибут Qt::WA_DeleteOnClose. quitOnLastWindowClosed не трогаю. Запускаю приложение с главным окном (дочернее вообще не запускаю) и закрываю главное окно. При этом вываливается ошибка (приложение остаётся в памяти): Цитировать warning: dep constructor warning: dep destructor warning: HEAP[dep.exe]: warning: Invalid Address specified to RtlFreeHeap( 003E0000, 0022FD30 ) Previous frame inner to this frame (corrupt stack?) При закрытии окна оно удаляется, согласно атрибуту Qt::WA_DeleteOnClose, удаляет детёнышей. Наверное срабатывает атрибут quitOnLastWindowClosed приложения, установленный по умолчанию, который пытается ещё раз удалить главное окно... Название: Re: Механизм parent'ов, деструкторов Отправлено: ритт от Декабрь 19, 2007, 21:33 считай, что у меня на лице тень смущения, но я все же спрошу:
в конструкторе ставишь дитёнку 0, а в деструкторе проверяешь дитёнка на не 0 перед попыткой закрыть? Название: Re: Механизм parent'ов, деструкторов Отправлено: pastor от Декабрь 19, 2007, 22:03 2 Cyrax: Покажи как создаешь гланое окно. Не в стеке случайно? Если да, то это не удивительно что будет падать при закрытии с флагом Qt::WA_DeleteOnClose :)
Название: Re: Механизм parent'ов, деструкторов Отправлено: Cyrax от Декабрь 19, 2007, 22:57 Блин, в стеке ведь... удаляется дважды...
Это Qt Eclipse integration так проект заделал, я уж забыл про это совсем... В данном случае идеологически корректным будет создание в стеке или в куче ? Название: Re: Механизм parent'ов, деструкторов Отправлено: pastor от Декабрь 19, 2007, 23:23 Блин, в стеке ведь... удаляется дважды... Это Qt Eclipse integration так проект заделал, я уж забыл про это совсем... В данном случае идеологически корректным будет создание в стеке или в куче ? Если юзаеться Qt::WA_DeleteOnClose, то виджет должен быть создан в куче. Инече будет двойное удаление |