Russian Qt Forum
Май 22, 2024, 14:57 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: Удаление классов в Qt  (Прочитано 30337 раз)
Evgeniya
Гость
« : Август 13, 2009, 14:35 »

Есть главная форма, из которой вызывается другая форма, а из нее третья и т.д. может быть
В документации по Qt написано, что нельзя самостоятельно удалять созданные экземпляры классов если они унаследованы от QObject, т.к. Qt сама заботится об освобождении памяти. Что же получается на практике, при создании диалогов им передается указатель на класс главного диалога и при закрытии дочерних диалогов их классы не удаляются, а удаляются только тогда когда будет закрыто главное окно. Но раз при каждом вызове создаётся новый экземпляр класса и не удаляется старый при закрытии дочерних диалогов происходит утечка памяти.... каким образом можно это все побороть?
Записан
spectre71
Гость
« Ответ #1 : Август 13, 2009, 14:40 »

В документации по Qt написано, что нельзя самостоятельно удалять созданные экземпляры классов если они унаследованы от QObject,
Такого в документации нет и не может быть!
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #2 : Август 13, 2009, 14:43 »

Улыбающийся

есть 2 варианта:
1. Либо создавать новые формы и им в конструктор засовывать параметр parent от главной формы - и тогда не придется их удалять перед завершением приложения
2. Либо создавать новые формы ничо им не передавая - но удалять их "вручную"

ЗЫ: вроде так , если не путаю
Записан

ArchLinux x86_64 / Win10 64 bit
Evgeniya
Гость
« Ответ #3 : Август 13, 2009, 14:46 »

Цитировать
Такого в документации нет и не может быть!
Значит я не правильно поняла (((
Значит все-таки нужно удалять все динамически созданные объекты?Непонимающий
Я так понимаю, что если они все имеют родителя, то сами удалятся при закрытии главного окна...значит их можно удалять при закрытии определенного диалога,перегрузив, например метод closeEvent(QCloseEvent *event)?? я правильно понимаю???
Записан
spectre71
Гость
« Ответ #4 : Август 13, 2009, 15:02 »

Цитировать
Такого в документации нет и не может быть!
Значит я не правильно поняла (((
Значит все-таки нужно удалять все динамически созданные объекты?Непонимающий
Я так понимаю, что если они все имеют родителя, то сами удалятся при закрытии главного окна...значит их можно удалять при закрытии определенного диалога,перегрузив, например метод closeEvent(QCloseEvent *event)?? я правильно понимаю???
Динамически созданные объекты унаследованные от QObject.
1) Если при создании не указан парент, то объект необходимо уничтожить самостоятельно
2) Если при создании указан парент, то объект удалиться при уничтожении парента, но и в этом этом случае объект можно удалить самостоятельно(до уничтожения парента). Просто при самостоятельном удалении он отвяжется от парента.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #5 : Август 13, 2009, 19:10 »

Цитировать
о объект удалиться при уничтожении парента, но и в этом этом случае объект можно удалить самостоятельно(до уничтожения парента). Просто при самостоятельном удалении он отвяжется от парента.
Что-то я в этом сильно сомневаюсь
Записан

Юра.
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #6 : Август 13, 2009, 19:11 »

При последующем удалении родителя, родитель неприятно вякнет
Записан

Юра.
spectre71
Гость
« Ответ #7 : Август 13, 2009, 19:12 »

При последующем удалении родителя, родитель неприятно вякнет
Ничего подобного.
Записан
denka
Гость
« Ответ #8 : Август 13, 2009, 19:18 »

Цитировать
о объект удалиться при уничтожении парента, но и в этом этом случае объект можно удалить самостоятельно(до уничтожения парента). Просто при самостоятельном удалении он отвяжется от парента.
Что-то я в этом сильно сомневаюсь

Елси заглянешь в исходники то убедишься что Spectre  прав.
Код:
QObject::~QObject()
{
   ....


    if (d->parent)        // remove it from parent object
        d->setParent_helper(0);
   .....

}

Так как деструктор у QObject виртуальный то это справедливо для всей иерархии
Записан
SABROG
Гость
« Ответ #9 : Август 13, 2009, 21:36 »

Цитировать
каким образом можно это все побороть?

Нормальный и безопасный метод QObject::deleteLater().

Цитировать
что нельзя самостоятельно удалять созданные экземпляры классов если они унаследованы от QObject

А где такое написано?
Записан
spectre71
Гость
« Ответ #10 : Август 13, 2009, 22:08 »

Нормальный и безопасный метод QObject::deleteLater().
Не надо запутывать..., это  к поставленному вопросу не относится, здесь речь шла об обычном удалении объекта унаследованного от QObject.
QObject::deleteLater() - необходим в определенных случаях в "мультипоточных" приложениях(корявинько написал Улыбающийся)
Записан
Evgeniya
Гость
« Ответ #11 : Август 13, 2009, 22:21 »

Все равно до конца не поняла....вот приведу часть кода
Код
C++ (Qt)
#ifndef ROSZDRAV_H
#define ROSZDRAV_H
 
#include <QtGui/QDialog>
#include <QSqlQueryModel>
#include <QString>
#include <QMessageBox>
#include <QSqlError>
#include <QSqlDatabase>
#include <QVariant>
#include <QAction>
#include <QMenu>
 
#include "ls.h"
#include "ui_roszdrav.h"
 
class LS;
class Roszdrav : public QDialog
{
   Q_OBJECT
 
public:
   Roszdrav(QWidget *parent,QString text);
   ~Roszdrav();
   closeEvent(QCloseEvent *event)
 
   QSqlQueryModel *ls;
   LS *l;
private:
   Ui::RoszdravClass ui;
private slots:
  void add();
};
 
#endif // ROSZDRAV_H
 
Код
C++ (Qt)
Roszdrav::Roszdrav(QWidget *parent,QString text)
          :QDialog(parent)
{
ui.setupUi(this);
createActions();
this->setWindowTitle("ЛС из Росздрава");
ls=new QSqlQueryModel(this);
str="SELECT Roszdrav.id,Roszdrav.mnn,Roszdrav.rf_mnn_terr_prog, "
               "Roszdrav.name_med,Roszdrav.Form_vipuska,Roszdrav.producer, "
               "Roszdrav.kv_all,Roszdrav.price,Roszdrav.status "
       "FROM Roszdrav "
       "WHERE rf_mnn_terr_prog is not NULL and name_med like '"+text+"%' "
       "ORDER BY                 Roszdrav.name_med,Roszdrav.Form_vipuska,Roszdrav.kv_all,Roszdrav.price";
ls->setQuery(str);
namecolumns();
ui.tableLS->setModel(ls);
connect(ui.add,SIGNAL(clicked()),this,SLOT(add()));
this->setFixedSize(899,300);
}
void Roszdrav::closeEvent(QCloseEvent *event){
delete ls;
if(l!=NULL) delete l;
event->accept();
}
void Roszdrav::add(){
l=new LS(this);
if(l->exec()==QDialog::Accepted){
                      ls->setQuery(str);
while (ls->canFetchMore()) ls->fetchMore();
sizecolumns();
QModelIndexList indexList = ls->match(ls->index(0,0),Qt::DisplayRole,l->roszdid,1, Qt::MatchExactly);
QModelIndex index=indexList.first();
int ind =index.row();
ui.tableLS->selectRow(ind);
}
      delete l;
}
 

насколько правильно я освобождаю память??
А класс class Roszdrav в свою очередь вызывается в другом классе
« Последнее редактирование: Август 13, 2009, 22:26 от Evgeniya » Записан
BlackTass
Гость
« Ответ #12 : Август 13, 2009, 22:35 »

Ну я бы посоветовал после
delete l;
поставить еще
l = NULL;

(это в методе add() ).

И еще вопрос. Зачем вам одновременно #include "ls.h" и class LS; ?
Вы либо второе удалите, либо первое в цппшник перенесите. А вообще хорошим тоном считается минимум инклюдов в хедерах. Большая часть их у вас просто не нужна, а нужна лишь уже в цппшнике.
Записан
ритт
Гость
« Ответ #13 : Август 14, 2009, 01:50 »

вообще, ужасно, конечно Улыбающийся
но если без придирок, то память в конечном счёте всё-таки освободится (если приложение не свалится в closeEvent Улыбающийся )
Записан
BlackTass
Гость
« Ответ #14 : Август 14, 2009, 02:43 »

но если без придирок, то память в конечном счёте всё-таки освободится (если приложение не свалится в closeEvent Улыбающийся )

по идее обязано свалиться в большинстве случаев
Записан
Страниц: [1] 2 3 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.138 секунд. Запросов: 23.