Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на 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, а азы не знаешь.

Есть немного :mellow:


Цитата
Потому что у них есть родители, которые удаляют их при своем уничтожении.

У кого есть родители?

Автор: 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)