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

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

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

вот и мне не очень нравится это Грустный поэтому и обратилась к вам за помощью...
вообще, ужасно, конечно Улыбающийся
но если без придирок, то память в конечном счёте всё-таки освободится (если приложение не свалится в closeEvent Улыбающийся )
ну как тогда лучше сделать???вообще ничего не освобождать или что?Непонимающий?

или может в классе задать атрибут Qt::WA_DeleteOnClose?
« Последнее редактирование: Август 14, 2009, 06:23 от Evgeniya » Записан
BlackTass
Гость
« Ответ #16 : Август 14, 2009, 08:04 »

Добавив присвоение l = NULL; вы избежите падений.
Записан
Evgeniya
Гость
« Ответ #17 : Август 14, 2009, 08:09 »

А если в классе задать атрибут Qt::WA_DeleteOnClose?
то может и не понадобится closeEvent???
Записан
ритт
Гость
« Ответ #18 : Август 14, 2009, 08:10 »

Добавив присвоение l = NULL; вы избежите падений.
а убрав "if(l!=NULL) delete l;" - тем-более Улыбающийся
Записан
Evgeniya
Гость
« Ответ #19 : Август 14, 2009, 08:23 »

значит мне вообще не нужно delete l???
просто этот класс может вызываться много раз и соответственно каждый раз будет выделяться память для l, пока не закроется главное приложение Roszdrav
Записан
BRE
Гость
« Ответ #20 : Август 14, 2009, 08:32 »

значит мне вообще не нужно delete l???
просто этот класс может вызываться много раз и соответственно каждый раз будет выделяться память для l, пока не закроется главное приложение Roszdrav
Удалять l в closeEvent не надо, ведь его удаление происходит в add.
Hint: А почему не создавать LS в методе add на стеке? И убрать указатель на l из класса?
Код:
void Roszdrav::add() {
        LS l(this);
        if( l.exec()==QDialog::Accepted ) {
        ...
        }
}
Записан
SABROG
Гость
« Ответ #21 : Август 14, 2009, 08:37 »

Чтобы не мучаться с присвоением NULL для QObject'a можно использовать QPointer.

Но я бы сделал рефакторинг.
Код
C++ (Qt)
class Roszdrav : public QDialog
{
   Q_OBJECT
 
public:
   Roszdrav(QWidget *parent,QString text);
   ~Roszdrav();
   closeEvent(QCloseEvent *event)
 
   QSqlQueryModel *ls;
   LS *l;
 

Указатели тут можно заменить на QSharedPointer. Если им присваивать новые указатели, то старый указатель автоматически удалиться, если его больше никто не использует. Точно также при уничтожении диалога указатели сами уничтожатся. Или можно использовать аггрегацию, но тут надо смотреть конкретно на реализацию класса LS.

А вообще тут будет небольшая утечка памяти:

Код
C++ (Qt)
ui.tableLS->setModel(ls);
 
Если диалог будет вызываться сотни раз, то созданные объекты QSelectionModel внутри класса QTableView никогда не удаляться. Поэтому лучше использовать существующую модель, а не создавать её каждый раз заново.

Цитировать
или может в классе задать атрибут Qt::WA_DeleteOnClose?
Указатели внутри класса это не удалит.

Цитировать
Не надо запутывать..., это  к поставленному вопросу не относится, здесь речь шла об обычном удалении объекта унаследованного от QObject.
QObject::deleteLater() - необходим в определенных случаях в "мультипоточных" приложениях(корявинько написал)
Оно всегда лучше чем обычный delete. Разве что, если в приложении вообще цикл событий не используется.
Записан
BRE
Гость
« Ответ #22 : Август 14, 2009, 08:42 »

А вообще тут будет небольшая утечка памяти:
Код
C++ (Qt)
ui.tableLS->setModel(ls);
 
Если диалог будет вызываться сотни раз, то созданные объекты QSelectionModel внутри класса QTableView никогда не удаляться. Поэтому лучше использовать существующую модель, а не создавать её каждый раз заново.
Почему? У модели указан parent, при удалении диалога будет удаляться модель.

Оно всегда лучше чем обычный delete. Разве что, если в приложении вообще цикл событий не используется.
Опять же, почему?
Записан
Evgeniya
Гость
« Ответ #23 : Август 14, 2009, 08:56 »

Удалять l в closeEvent не надо, ведь его удаление происходит в add.
Hint: А почему не создавать LS в методе add на стеке? И убрать указатель на l из класса?
Код:
void Roszdrav::add() {
        LS l(this);
        if( l.exec()==QDialog::Accepted ) {
        ...
        }
}
А если мне l нужна как глобальная переменная....то как мне ее задать ??
Код
C++ (Qt)
LS l;
l=LS(this);
 
не получается

Записан
SABROG
Гость
« Ответ #24 : Август 14, 2009, 09:04 »

Почему? У модели указан parent, при удалении диалога будет удаляться модель.
Вообще да, что-то я подумал, что парентом будет вьюха. Тогда получается косяк, при закрытии диалога уничтожается модель на вьюхе главного окна. Но лучше взять за правило использовать одну модель, ситуации разные могут быть.

Цитировать
Опять же, почему?
Хотя бы потому, что deleteLater() можно вызывать несколько раз на один и тот же объект, даже из разных потоков.

А если мне l нужна как глобальная переменная....то как мне ее задать ??
Код
C++ (Qt)
LS l;
l=LS(this);
 
не получается

Давно ли вы дружите с C++?

Код
C++ (Qt)
class Roszdrav : public QDialog
{
   Q_OBJECT
 
public:
   Roszdrav(QWidget *parent,QString text);
   ~Roszdrav();
   closeEvent(QCloseEvent *event)
 
   QSqlQueryModel *ls;
   LS l;
 
Roszdrav::Roszdrav(QWidget *parent,QString text)
          :QDialog(parent), l(this)
{
 
« Последнее редактирование: Август 14, 2009, 09:06 от SABROG » Записан
BRE
Гость
« Ответ #25 : Август 14, 2009, 09:11 »

Хотя бы потому, что deleteLater() можно вызывать несколько раз на один и тот же объект, даже из разных потоков.
Тебе не кажется, что такой подход к написанию... ээээ... какбы не очень красив.  Подмигивающий
Если у меня есть желание и возможность грохнуть объект немедленно, то зачем мне ждать очередного входа в обработку очереди событий?
В некоторых случаях использовать deleteLater удобно, в некоторых необходимо, но использовать его всегда, вместо delete IMHO не оправдано.  Улыбающийся
Записан
BRE
Гость
« Ответ #26 : Август 14, 2009, 09:13 »

А если мне l нужна как глобальная переменная....то как мне ее задать ??
А зачем это тебе?
В методе add ты создаешь и убиваешь этот объект, т.е. живет он только в момент выполнения add.
Записан
SABROG
Гость
« Ответ #27 : Август 14, 2009, 09:17 »

Если у меня есть желание и возможность грохнуть объект немедленно, то зачем мне ждать очередного входа в обработку очереди событий?

Чтобы синхронизировать работу потоков? Это не панацея. Если другого выбора нет, то можно.
Записан
spectre71
Гость
« Ответ #28 : Август 14, 2009, 09:17 »

Хотя бы потому, что deleteLater() можно вызывать несколько раз на один и тот же объект, даже из разных потоков.
Не может такого быть.
Цитировать
Note: It is safe to call this function more than once; when the first deferred deletion event is delivered, any pending events for the object are removed from the event queue.
Только до тех пор пока объект не удален.
Насколько я понял, можно сделать так
MyObj* Obj;

Код
C++ (Qt)
void d (void) {
 Obj->deleteLater();
 Obj->deleteLater();
}
 

А так будет ошибка
Код
C++ (Qt)
void d (void) {
 Obj->deleteLater();
 QApplication::processEvents();
 Obj->deleteLater();
}
 
Записан
BRE
Гость
« Ответ #29 : Август 14, 2009, 09:25 »

Чтобы синхронизировать работу потоков? Это не панацея. Если другого выбора нет, то можно.
Можно, но не ...
Цитировать
Оно всегда лучше чем обычный delete.
Подмигивающий
Записан
Страниц: 1 [2] 3 4   Вверх
  Печать  
 
Перейти в:  


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