Название: Как правильно удалять объекты? Отправлено: usr00210 от Август 31, 2010, 03:57 Если я создаю дочерние объекты/элементы, должен ли я явно, через delete например, удалять их, скажем в деструкторе парента?
Или же сам парент позаботится о своих детях? Есть ли какие-то исключения, особые правила и т.п. на эту тему в Кьют? Спасибо! Название: Re: Как правильно удалять объекты? Отправлено: Пантер от Август 31, 2010, 06:33 Если при создании виджета ты указываешь ему родителя, то родитель после смерти прибьет его. Вручную это можно не делать.
Название: Re: Как правильно удалять объекты? Отправлено: usr00210 от Август 31, 2010, 07:10 Если при создании виджета ты указываешь ему родителя, то родитель после смерти прибьет его. Вручную это можно не делать. т.е. именно можно? и даже если я буду добросовестно удалять все созданные динамические объекты, это не приведет к беде? И такие вложенные конструкции типа: QApplication <- *MainWindow <- *VLayout <- { *Button1, *Button2, ... } будут корректно обрабатываться с освобождением всех занятых ресурсов? ПС. фраза "указываешь ему родителя" означает MyChildWidget( this ) внутри парента? Т.е. если без this, то парент ничего знать будет о ребенки и не сможет правильно освободить ресурсы? Название: Re: Как правильно удалять объекты? Отправлено: lit-uriy от Август 31, 2010, 07:59 >>означает MyChildWidget( this )
не обязательно "этот". Родителем может быть и другой виджет, всё зависит от иерархии объектов. Если иерархия существует, т.е. аргумент "parent" не был оставлен пустым. Тогда удаление будет происходить автоматически. Правда в компоновщик можно помещать виджеты не указывая родителя. Т.к. компоновщик назначит им в качестве родителя своего родителя. Название: Re: Как правильно удалять объекты? Отправлено: Alex_cs_gsp от Август 31, 2010, 08:45 Пока логики не нашел, так что приходится для каждого метода, который принимает указатель на объект, лезть в справку и выискивать будет ли он его прибивать или нет.
Название: Re: Как правильно удалять объекты? Отправлено: usr00210 от Август 31, 2010, 09:53 >>означает MyChildWidget( this ) не обязательно "этот". Родителем может быть и другой виджет, всё зависит от иерархии объектов. Если иерархия существует, т.е. аргумент "parent" не был оставлен пустым. Тогда удаление будет происходить автоматически. Правда в компоновщик можно помещать виджеты не указывая родителя. Т.к. компоновщик назначит им в качестве родителя своего родителя. выделенное не понял. Если я создаю кнопку на форме и не указываю эту форму в качестве парента, то кнопка не появится при вызове метода форма->show; т.е. парент ничего не знает о кнопке. Название: Re: Как правильно удалять объекты? Отправлено: usr00210 от Август 31, 2010, 09:58 Пока логики не нашел, так что приходится для каждого метода, который принимает указатель на объект, лезть в справку и выискивать будет ли он его прибивать или нет. приведите пожалуйста два примера в которых происходит автоудаление и в которых надо это делать самому. спасибо! Название: Re: Как правильно удалять объекты? Отправлено: kuzulis от Август 31, 2010, 10:23 Цитировать выделенное не понял. Если я создаю кнопку на форме и не указываю эту форму в качестве парента, то кнопка не появится при вызове метода форма->show; т.е. парент ничего не знает о кнопке. Ну типа да. Только это Цитировать Если я создаю кнопку на форме некорректно в данном случае потому что раз вы не указываете родителя то => кнопка не будет принадлежать этой форме!Для того чтобы она показалась необходимо вызвать где-то в коде: Код: ... Под компоновщиком тут Юрий имел ввиду Layout. При добавлении в Layout кнопки созданной без родителя автоматически Layout ей присвоит своего родителя! т.е. (псевдокод): Код: ... Название: Re: Как правильно удалять объекты? Отправлено: Denjs от Август 31, 2010, 10:30 Правда в компоновщик можно помещать виджеты не указывая родителя. Т.к. компоновщик назначит им в качестве родителя своего родителя. выделенное не понял.Например QGridLayout. Когда ему дают виджет длч размещения в определенных ячейках - он назначает переданному виджету родителем тот виджет, на котором он сам "лежит". Название: Re: Как правильно удалять объекты? Отправлено: usr00210 от Август 31, 2010, 11:47 понятно, спасибо!
Название: Re: Как правильно удалять объекты? Отправлено: break от Сентябрь 01, 2010, 01:10 В справке по Qt написано про автоматическую уборку мусора через QObject (одна из первых статей в ассистенте по QObject) - то есть все QObject-ы этим свойством обладают (не только виджеты).
А повторное удаление не приводит к проблеме (например если вы все же удаляете дочерний объект сами) т.к. QObject родитель работает с дочерними объектами через "умные указатели" (QPointer). И в деструкторе в момент прохода по чилдам имеет возможность проверить существует ли этот чилд и только если да - пытается его удалить... Название: Re: Как правильно удалять объекты? Отправлено: Alex_cs_gsp от Сентябрь 01, 2010, 14:21 А как знает предок что потомок был удален, если я delete вызываю для области памяти? Используется какая-то глобальная таблица?
Например, QWidget *pwgt = new QWidget(); pVLayout->addWidget(pwgt); delete pwgt; Откуда лейаут знает, что виджет был удален. Я так понял тут используется какой-то другой механизм, вместо подсчета ссылок? Или банально деструктор потомка находит предка и обнуляет соответствующую ссылку у объекта предка? Название: Re: Как правильно удалять объекты? Отправлено: break от Сентябрь 01, 2010, 14:27 Чем QPointer в данном случае не заработает? В исходники не смотрел только предполагаю что работает через него. Зачем чилду лезть в парент? У парента список чилдов - но не прямых "тупых указателей", а список указателей "завернутых в QPointer", которые автоматически обнуляются при удалении объекта.
Название: Re: Как правильно удалять объекты? Отправлено: BRE от Сентябрь 01, 2010, 14:30 Откуда лейаут знает, что виджет был удален. Я так понял тут используется какой-то другой механизм, вместо подсчета ссылок? Другой.В конструкторе QObject (если parent != 0) указатель на конструируемый объект добавляется в специальный список parent-объекта. При разрушении объекта в деструкторе он себя вычеркивает из списка parent-объекта. А при разрушении самого parent-объекта в его деструкторе будут удалены все объекты содержащиеся в этом списке. Название: Re: Как правильно удалять объекты? Отправлено: BRE от Сентябрь 01, 2010, 14:49 Чем QPointer в данном случае не заработает? В исходники не смотрел только предполагаю что работает через него. Зачем чилду лезть в парент? У парента список чилдов - но не прямых "тупых указателей", а список указателей "завернутых в QPointer", которые автоматически обнуляются при удалении объекта. Там используется обычный QObjectList, т.е. просто QList<QObject*> |