Версия для печати темы
Форум на CrossPlatform.RU _ Qt Общие вопросы _ Динамические объекты в Qt?
Автор: registr 10.10.2011, 18:37
Как подчищаются динамические объекты (через new)? Освобождается память операционной системой или какими-то Qt-шными средствами?
Перефразирую вопрос. Почему в Qt Examples and Demos динамические объекты не удалаются через delete в деструкторах?
Автор: RazrFalcon 10.10.2011, 19:12
Чистим через delete и delete[].
В примерах нет, да. ХЗ почему. В Qt вообще деструкторы редко используются.
При том у них есть свой deleteLater().
Также можно юзать умные указатели. Кьютешные.
http://developer.qt.nokia.com/wiki/Smart_Pointers_Russian
Автор: silver47 10.10.2011, 19:20
Цитата
Почему в Qt Examples and Demos динамические объекты не удалаются через delete в деструкторах?
Потому что у них есть родители, которые удаляют их при своем уничтожении. Простой пример:
MyWidget::MyWidget(QWidget *parent) : QWidget(parent){
QVBoxLayout *mainLay = new QVBoxLayout(this); // создаю главный лэйаут и присваиваю ему родителем текущий класс, при уничтожении класса этот лэйатут будет уничтожен
mainLai->addWidget(new QLabel("А это простой элемент, внутри лэйатуа"\n"Он будет уничтожен при уничтожении лэйатуа автоматически"));
this->setLayout(mainLay);
}
Автор: registr 10.10.2011, 20:20
Цитата
Потому что у них есть родители, которые удаляют их при своем уничтожении. Простой пример:
Я имел в виду динамический объект верхнего уровня, то есть на вершине иерархии.
Например, Qt 4.7 Examles and Demos, OpenGL, Hello GL Example
Там есть два класса GLWidget и Window. Я цитирую файл window.cpp
Window::Window()
{
glWidget = new GLWidget;
Объект "glWidget" динамический, но он не объект-потомок. Нужно либо указать, что он объект-потомок
Window::Window()
{
glWidget = new GLWidget(this);
либо удалить его в деструкторе
Window::~Window()
{
delete glWidget;
Но этого в примере нет. Я не понимаю почему.
Вообщем разобрался
Автор: silver47 11.10.2011, 5:06
Потому как человек, который писал пример посчитал, что небольшая утечка памяти не критична?
Автор: Litkevich Yuriy 11.10.2011, 7:37
Цитата(RazrFalcon @ 10.10.2011, 22:12)
В Qt вообще деструкторы редко используются.
При том у них есть свой deleteLater().
RazrFalcon, уже столько дней с Qt, а азы не знаешь.
Ответ:
Цитата(silver47 @ 10.10.2011, 22:20)
Потому что у них есть родители, которые удаляют их при своем уничтожении.
Цитата(registr @ 10.10.2011, 23:20)
Я имел в виду динамический объект верхнего уровня, то есть на вершине иерархии.
а смысл его удалять? он удалится при закрытии программы средствами ОСьки
Автор: registr 11.10.2011, 13:11
Цитата(silver47 @ 11.10.2011, 5:06)
Потому как человек, который писал пример посчитал, что небольшая утечка памяти не критична?
Неа, там если детальнее разобраться с примером, то получается, что действительно создается дерево объектов. А объект верхнего уровня создан в стеке, поэтому выйдя за область видимости он удалится и удалит все дерево.
PS примеры написаны профессионально, просто, как это всегда бывает, надо было только подумать над ними
Цитата(Litkevich Yuriy @ 11.10.2011, 8:37)
а смысл его удалять? он удалится при закрытии программы средствами ОСьки
Как люди говорят, это мовитон
Действительно все объекты верхнего уровня создают в стеке, а не в куче, т.е. нединамически
Автор: RazrFalcon 11.10.2011, 16:52
Цитата(Litkevich Yuriy @ 11.10.2011, 7:37)
RazrFalcon, уже столько дней с Qt, а азы не знаешь.
Есть немного
Цитата
Потому что у них есть родители, которые удаляют их при своем уничтожении.
У кого есть родители?
Автор: silver47 11.10.2011, 18:48
Цитата
Как люди говорят, это мовитон Действительно все объекты верхнего уровня создают в стеке, а не в куче, т.е. нединамически
Ой ли? мой же пример выше:
MyWidget::MyWidget(QWidget *parent) : QWidget(parent){
QVBoxLayout *mainLay = new QVBoxLayout(this);
}
Где создается mainLay на стеке или на куче? Чего с ним будет, когда мы выйдем за пределы видимости? Верный ответ здесь:
Цитата
он удалится при закрытии программы средствами ОСьки
Или Вы вообще про объект MyWidget?
Автор: registr 11.10.2011, 20:35
Цитата
Или Вы вообще про объект MyWidget?
Да-да, объект MyWidget нужно создавать нединамически, или же если есть главное окно, то тогда динамический объект класса MyWidget включается в деверо, на вершине которого нединамический объектглавного окна. Короче объект верхненго уровня всегда нужно делать в стеке, а объекты-потомки в куче.
Цитата(RazrFalcon @ 11.10.2011, 17:52)
У кого есть родители?
Управление памятью с помощью дерева объектов
http://doc.qt.nokia.com/latest/objecttrees.html
Короче, есть объекты-родители и объекты-потомки, все они связаны в дерево объектов. На вершине иерархии -- объект верхненого уровня. Когда удаляется объект-родитель, то удаляются все его объекты-потомки. В частности там объясняется, почему объекты-потомки должны быть динамическими. А объект верхнего уровня нужно создавать в стеке.
Автор: registr 11.10.2011, 21:29
MyWidget::MyWidget(QWidget *parent) : QWidget(parent){
QVBoxLayout *mainLay = new QVBoxLayout;
mainLai->addWidget(new QLabel("А"));
this->setLayout(mainLay);
}
Кстати, в твоем коде не нужно писать
QVBoxLayout *mainLay = new QVBoxLayout(
this);
так как родительско-потомковая связь установится при
this->setLayout(mainLay);
Автор: Litkevich Yuriy 12.10.2011, 20:20
Цитата(RazrFalcon @ 11.10.2011, 19:52)
У кого есть родители?
SameObject *parent = new SameObject(); -- у этого объекта нет родителя (его надо удалять самостоятельно)
...
OtherObject * o = new OtherObject(parent); -- а у этого объекта - ЕСТЬ (его удалит родитель, когда будет сам удалятся)
Посмотри внимательно на описание конструктора QObject и его наследников. Они принимают в качестве аргумента родительский объект. А внутри кода, в том числе собственных объектов, указатель на родителя передаётся в базовый класс:
MyObject::MyObject(QObject *parent) : QObject(parent) -- мы передаём parent в конструктор базового класса, чтобы вся механика родительско-дочерних связей работала штатным образом.
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)