Название: Вопрос про удаление QObject находящегося в иерархии Отправлено: kamil от Май 03, 2015, 13:12 В программе возникла проблема, и я уверен, что многие с ней сталкивались.
Есть класс Plot отвечающий за отрисовку одного графика. Среди членов класса - указатели на QWidget (имя графика, цвет, и т. п.). Эти QWidget должны удаляться в двух местах: - автоматически при выходе из программы, так как они в иерархии QObject являются потомками QMainWindow - в ручную, когда удаляется сам экземпляр класса Plot, например когда нужно загрузить новые графики из другого файла, а старые удалить. Если в деструкторе Plot написать: Код: delete pointerToWidget; Если вместо ручного удаления просто скрывать pointerToWidget, чтобы он во время выхода сам удалился - по мере открывания файлов объекты будут скапливаться, забивая память. Как обычно поступают в такой ситуации? Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Bepec от Май 03, 2015, 13:29 Вы сами контролируйте состояние.
Сделайте обнуление указателя и добавьте проверку при его удалении. Код: if (pointerToWidget) И да, не забудьте обнулить указатель в конструкторе, а то креш словите :) Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Old от Май 03, 2015, 13:35 Не нужна эта бесполезная проверка на 0, delete сам прекрасно это проверяет.
Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Igors от Май 03, 2015, 13:49 Как обычно поступают в такой ситуации? Используют QPointer Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: kamil от Май 03, 2015, 17:18 Bepec, спасибо, убрал виджеты из иерархии и удаляю вручную - всё нормально.
Old, да, проверка не нужна, delete нормально есть NULL Igors, тут вроде как и без QPointer можно обойтись - практически как и в любой другой ситуации... Update: Bepec, ничего не нормально. При попытке убрать виджет из иерархии (setParent(NULL)), все виджеты оказываются в отдельных окнах (странно, я думал иерархия QObject и иерархия в ui это разные вещи). Как ещё можно самому контролировать время жизни виджетов? Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Old от Май 03, 2015, 19:28 Проверьте ещё раз, если вы виджет удаляете руками, например, в деструктор, то он автоматически вычеркивается из списка своего parent и не будет удаляться автоматически, при разрушении parent.
Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: lit-uriy от Май 03, 2015, 20:04 Наследников QObject нужно удалять через их метод deleteLater()
Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Bepec от Май 03, 2015, 20:58 Нуууу, тут непонятно что у вас творится.
Тут надо выбрать один подход - или вы держитесь за систему Qt, или вы сами управляете объектами. PS выход подсказывает lit-uriy :) Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: kamil от Май 03, 2015, 23:23 Bepec, как мне вручную контролировать время жизни объектов, которые являются частью иерархии QMainWindow?
lit-uriy, deleteLater() я использовать не могу - я уже говорил что к тому моменту как вызывается деструктор класса Plot, объект может быть удалён уже самим qt. Я не знаю как можно проверить удалён объект или нет, не используя QPointer. Old, вы правы, если я удалил объект первым, то через иерархию QMainWindow он не станет удаляться. А если первым удалит сам Qt? Попробую объяснить ситуацию ещё раз. Деструкор некоторого объекта вызывается в двух случаях: - во время работы программы. В этом случае нужно удалить некоторый QWidget вручную. - когда закрывается программа. В этом случае QWidget уже может быть удалён самим Qt как потомок в иерархии QMainWindow. Действительно, как говорил Верес, нужно, например, управлять временем жизнью QObject самостоятельно. Как это сделать я не знаю. Либо же оставить право Qt удалять объекты, но проверять, не удалён ли уже объект, прежде чем вызывать delete. Как это сделать я тоже не знаю. В голову пока приходит только QPointer. Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Old от Май 04, 2015, 02:07 Дочернии объекты удаляются только при удалении родительского объекта. Т.е. в вашем случае, при удалении главного окно. Как правило это происходит в функции main при завершении программы. До этого момента, Qt не сможет ничего удалить, поэтому смело удаляйте нужные объекты руками, там где это нужно.
Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Igors от Май 04, 2015, 09:01 Igors, тут вроде как и без QPointer можно обойтись - практически как и в любой другой ситуации... Можно, но зачем? Не вижу какие минусы имеет это решение, тем более оно штатное. Может что-то "оптимизировать" собрались? :) Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Bepec от Май 04, 2015, 11:50 to Old:
Проверка на NULL нужна не для delete, а для пользователя. Он вполне бы не инициализировал нуллом в конструкторе и поймал непонятный креш. Лишь дополнительный контроль за собой, хотя самоуверенные и люди с опытом, могут не пользоваться :D Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Old от Май 04, 2015, 12:22 to Old: Если пользователь не инициализирует указатель в конструкторе, он словит тотже краш. Эта проверка ему ничем не поможет.Проверка на NULL нужна не для delete, а для пользователя. Он вполне бы не инициализировал нуллом в конструкторе и поймал непонятный креш. Лишь дополнительный контроль за собой, хотя самоуверенные и люди с опытом, могут не пользоваться :D Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Bepec от Май 04, 2015, 21:00 Эта проверка поможет тем, что на ней проверка на Null явная и её можно пошагово разобрать.
И понять, что указатель не равен NULL, а не "что то произошло внутри delete, а вот что - хрен разбрёшь" :) Собственно это для удобства программиста и отладки. Акцентирую - отладки, а не для написания совершенного кода :D Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Old от Май 04, 2015, 21:08 Тогда лучше так:
Код
Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Bepec от Май 04, 2015, 21:33 Не возводите предъосторожность в степень идиотизма :)
Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Old от Май 04, 2015, 21:35 Не возводите предъосторожность в степень идиотизма :) Это не более идиотизм, чем ваша проверка.Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Bepec от Май 04, 2015, 21:40 Ну давайте, расскажите мне, в чем ошибка в моём случае. Просто дополнительное условие, вынесенное в зону контроля программиста, а не стандартной библиотеки.
PS расскажите расскажите как это плохо, жрёт кучу тактов процессора на обработку. Давайте, откройте правду :) PPS и расскажите сотням новичков, которые могут отловить этот тонкий нюанс простой точкой остановки. Не все с рождения и начала программирования знают о тонкостях :D Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Old от Май 04, 2015, 21:49 Это не нужно.
Вам это не поможет, а новички после этого и так задумаются о ненужности такой проверки. Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Bepec от Май 04, 2015, 21:54 Вы не путайте код профессиональный и код для работы.
Вообще профессиональный код выглядит как будто алфавит взбесился, никаких пояснений, многострочные формулы и отсутствие комментариев. Но с ним работать в дальнейшем невозможно. А в данном случае как раз идёт проверка на неочевидную ошибку, которую можно отладить за 5 минут имея малейшее представление об указателях. А не бежать с криками на форум - почему я делал программу по коду программы Old и у меня на delete ошибка? PS тьфу тьфу тьфу, не буду спорить. Каждый решает для себя. Хоть дефайнте delete как _d :) Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Old от Май 04, 2015, 21:58 Последний раз, попробуйте понять: эта проверка ничего не дает и не от чего не защищает. Она полностью бесколезна в любом коде.
Поток сознания про профкод и код для работы, даже не знаю как прокомментировать. :) Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Bepec от Май 04, 2015, 23:47 А я не буду спорить) Читать и понять мой комментарий вы не пробовали, так что приятного вам времени дня :D
PS лучше б вместо разведения споров и насмешек написали коротко и просто "этот код кажется МНЕ избыточным" :) Название: Re: Вопрос про удаление QObject находящегося в иерархии Отправлено: Old от Май 05, 2015, 06:57 А я не буду спорить) Читать и понять мой комментарий вы не пробовали, так что приятного вам времени дня :D Я это написал в первом своем посте этой темы. :)PS лучше б вместо разведения споров и насмешек написали коротко и просто "этот код кажется МНЕ избыточным" :) |