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

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

Страниц: [1] 2 3 ... 10   Вниз
  Печать  
Автор Тема: Основы удаления объектов  (Прочитано 85093 раз)
n4ela
Гость
« : Январь 08, 2010, 00:58 »

Привет всем. Я запутался когда надо удалять созданные объекты самому а когда они удалятся сами.
Вот приведу несколько ситуаций.
1. Я создал класс отнаследовав его от QWidget, в нем объявил и работал с несколькими объектами из qt(например qlabel и qpushbutton), я не переопределал деструктор в своем классе(т.е. его у меня вобще нет ).
При разрушение моего класса qlabel и qpushbutton очистят память?

2. Я создал класс отнаследовав его от QWidget, в нем объявил и работал с несколькими объектами из qt(например qlabel и qpushbutton), я переопределил деструктор и оставил его пустым.
При разрушение моего класса qlabel и qpushbutton очистят память?

3. Я создал класс отнаследовав его от QWidget, в нем объявил и работал с QList <QLabel* > testList. В середине выполнения программы я сделал testList.clear(). Я не переопределил деструктор в своем классе(т.е. его у меня вобще нет )
Память от label'ов очистится после clear(), после разрушения моего класса? не очистится ни когда и у меня не будет возможности добраться до памяти?

4. Я создал класс отнаследовав его от QWidget, в нем объявил и работал с несколькими объектами из qt(например qlabel и qpushbutton) и со сторонними библиотеками, я переопределил деструктор и оставил его пустым.
При разрушении моего класса объекты из qt очистят память, а из сторонних библиотек останутся?

5. Я создал класс отнаследовав его от QWidget, в нем объявил и работал с QList <что нибудь из сторонних библиотек > testList. В середине выполнения программы я сделал testList.clear(). Я не переопределал деструктор в своем классе(т.е. его у меня вобще нет )
Память не очистится ни когда и после clear у меня не будет возможности очистить память?

6. Я создал класс отнаследовав его от QWidget, в нем объявил и работал с несколькими объектами из qt(например qlabel и qpushbutton), я переопределил деструктор в своем классе и удалил все объекты с помощью delete
Я сделал лишнюю работу но не чего плохого не случится?
« Последнее редактирование: Январь 15, 2010, 23:16 от Dendy » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #1 : Январь 08, 2010, 01:10 »

Тебе хорошо бы почитать книжки по с++
Когда ты удаляешь QObject или его наследника, он удалит объекты, яляющиеся дочерними (то есть теми, для которых указан parent)
QWidget * main = new QWidget;
QLabel * lb = new QLabel(main);
QPushButton * button = new QPushButton;
delete main; // удалит main и lb, но НЕ button
Деструктор не переопределяется. Он реализовывается. Более того, ВСЕГДА есть деструктор по умолчанию. Написание ~MyClass() {} не меняет ничего. Ну вообще ничего - ты заменил дефолтный пустой деструктор своим пустым деструктором
Потому пункт 1 и 2 это одно и то же
3) clear не вызывает delete. Оно очищает список. Что было бы если бы у тебя было 2 списка? есть макрос qDeleteAll, но он НЕ вызывает clear()
4) удалятся только объекты с указанным родителем
5) да
6) да, можно и так сказать
Записан
SABROG
Гость
« Ответ #2 : Январь 08, 2010, 01:11 »

Это же проверяется быстрей, чем ты писал свой пост, сигнал

void QObject::destroyed ( QObject * obj = 0 )
Записан
Геннадий Пастухов
Гость
« Ответ #3 : Январь 08, 2010, 01:16 »

Привет всем. Я запутался когда надо удалять созданные объекты самому а когда они удалятся сами.

Общее правило стандартное С++-ное: автоматические объекты удалятся сами, созданные вручную через new необходимо удалять самому.
Записан
Dendy
Гость
« Ответ #4 : Январь 08, 2010, 01:28 »

Общее правило стандартное С++-ное: автоматические объекты удалятся сами, созданные вручную через new необходимо удалять самому.

Во-первых, что такое "автоматические обьекты"? Во-вторых не вижу связи, что выделенное через new нужно удалять самому. Qt наглядно демонстрирует, что это не так. К примеру QObject сам удалит дочерние обьекты, а QSharedDataPointer сам удалит руками выделенный экземпляр QSharedData.
Записан
n4ela
Гость
« Ответ #5 : Январь 08, 2010, 01:50 »

Общее правило стандартное С++-ное: автоматические объекты удалятся сами, созданные вручную через new необходимо удалять самому.
Как раз таки это меня и запутало, во всех книжках про qt написано, что дочерние объекты удалятся сами при уничтожения родителя. Вот сейчас просто решил уточнить, правильно ли я это понимаю, что уже знать наверняка.


Когда ты удаляешь QObject или его наследника, он удалит объекты, яляющиеся дочерними (то есть теми, для которых указан parent)
QWidget * main = new QWidget;
QLabel * lb = new QLabel(main);
QPushButton * button = new QPushButton;
delete main; // удалит main и lb, но НЕ button
Вот тут опять не понятно, приведу пример:
form.h
Код
C++ (Qt)
class Form : public QWidget
{
   Q_OBJECT
 
public:
   Form( QWidget *parent = 0 );
   ~Form();
 
private:
   QLineEdit *line;
   QPushButton *button;
};
#endif
form.cpp
Код
C++ (Qt)
Form::Form( QWidget *parent )
   :QWidget( parent )
{
   line = new QLineEdit( this )
   button = new QPushButton;
   QPushButton *testButton = new QPushButton;
}
 
main.cpp
Код
C++ (Qt)
int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   Form w;
   w.show();
   return a.exec();
}

По вашему примеру получается что button и testButton не удалятся
« Последнее редактирование: Январь 08, 2010, 02:02 от n4ela » Записан
Dendy
Гость
« Ответ #6 : Январь 08, 2010, 02:53 »

По вашему примеру получается что button и testButton не удалятся

Именно. А почему они должны удалиться?
Записан
ilot
Гость
« Ответ #7 : Январь 08, 2010, 06:55 »

Во-первых, что такое "автоматические обьекты"?
Автоматическими называются объекты созданные в стеке. Момент их создания, их количество и время уничтожения заранее известны компилятору, и он полностью отвечает за их жизненный цикл. Отсюда и название  - автоматические (вполне официальное; в стандарте есть даже ключевое слово auto).
Во-вторых не вижу связи, что выделенное через new нужно удалять самому. Qt наглядно демонстрирует, что это не так. К примеру QObject сам удалит дочерние обьекты, а QSharedDataPointer сам удалит руками выделенный экземпляр QSharedData.
В общем случае - да, удалять самому. Компилятор не контролирует ни создание динамических объектов, ни их уничтожение. QObject удалить свои дочерние объекты только в том случае, если вы при их создании явно укажите, что они его дочерние объекты, передав в конструкторе указатель на родителя. Именно поэтому в примере из предпоследнего поста button и testButton не удаляются при уничтожении экземпляра Form (форма не считает их дочерними). Так что это архитектурная особенность библиотеки, а не правило языка.

Как раз таки это меня и запутало, во всех книжках про qt написано, что дочерние объекты удалятся сами при уничтожения родителя. Вот сейчас просто решил уточнить, правильно ли я это понимаю, что уже знать наверняка.
Все так, но, как я уже написал выше, родственную связь нужно описывать явно, передавая указатель на родителя. Иначе никакой зачистки памяти не будет.
При использовании layout-ов указатель на родителя можно не передавать, посколько layout берет эту часть работы на себя.
Записан
niXman
Гость
« Ответ #8 : Январь 08, 2010, 07:12 »

Цитировать
Автоматическими называются объекты созданные в стеке.
именно в стеке!
а создание объекта при помощи new отменяет любую "автоматику".

Цитировать
в стандарте есть даже ключевое слово auto
да, но назначение это КС совсем иное Подмигивающий

Цитировать
QObject удалить свои дочерние объекты только в том случае, если вы при их создании явно укажите, что они его дочерние объекты, передав в конструкторе указатель на родителя.
уже отвечал: http://www.prog.org.ru/index.php?topic=11965.msg75045#msg75045

Цитировать
Так что это архитектурная особенность библиотеки, а не правило языка.
в данном контексте да.

Записан
Dendy
Гость
« Ответ #9 : Январь 08, 2010, 07:23 »

Так что это архитектурная особенность библиотеки, а не правило языка.

Собственно, автор и спрашивал про архитектурную особенность библиотеки. А правила языка думаю и так все знают. В Qt3 помимо QList, QDict и прочих были классы QPtrList, QPtrDict, которые действительно делали то, что спрашивается автор - удаляли данные по указателям. В Qt4 же их упразднили, теперь контейнеры занимаются только хранением указателей, никакого неявного выделения/удаления памяти они не делают.
Записан
ilot
Гость
« Ответ #10 : Январь 08, 2010, 07:32 »

Цитировать
в стандарте есть даже ключевое слово auto
да, но назначение это КС совсем иное Подмигивающий
Пока я понимаю так: Автоматические переменные автоматически создаются в стеке при входе в область видимости и автоматически уничтожаются при выходе из нее. На это обстоятельство можно указать явно, используя ключевое слово auto. Поскольку все локальные переменные являются автоматическими по умолчанию, то данное КС на практике не применяют (по крайней мере я не видел), а в язык оно включено для полноты.

Если вам известны другие значения КС auto, поделитесь пожалуйста.
Записан
niXman
Гость
« Ответ #11 : Январь 08, 2010, 07:44 »

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

Цитировать
На это обстоятельство можно указать явно, используя ключевое слово auto.
абсолютно не верно!
у этого КС, иной, гораздо более необходимый смысл.

Цитировать
Поскольку все локальные переменные являются автоматическими по умолчанию, то данное КС на практике не применяют (по крайней мере я не видел), а в язык оно включено для полноты.
никому этого не говори Смеющийся засмеют и заплюют.

вот: http://en.wikipedia.org/wiki/C%2B%2B0x#Type_inference
Записан
ilot
Гость
« Ответ #12 : Январь 08, 2010, 09:11 »

у этого КС, иной, гораздо более необходимый смысл.

Цитировать
Поскольку все локальные переменные являются автоматическими по умолчанию, то данное КС на практике не применяют (по крайней мере я не видел), а в язык оно включено для полноты.
никому этого не говори Смеющийся засмеют и заплюют.

вот: http://en.wikipedia.org/wiki/C%2B%2B0x#Type_inference
Приведенная тобой ссылка относится к новому еще разрабатываемому стандарту С++0x. Там явно указано, что использование КС auto в таком контексте относится к усовершенствованию ядра языка. Это значит в действующем стандарте ничего подобно нету. Я же имел ввиду действующую сейчас редакцию C++03. И когда говорил, что я не видел на практике примеров применения, я имел ввиду исходные тексты рабочих программ.

Я не считаю себя опытным программистом на С++, поэтому многое могу не знать. Но нигде в литературе др. применения auto я тоже не встречал. Если кто знает, то прошу поделиться. Мне это действительно интересно. Форум на то и нужен, чтобы общаться и делиться знаниями.

P.S. спасибо за ссылку niXman, почитаю на досуге  Улыбающийся
Записан
niXman
Гость
« Ответ #13 : Январь 08, 2010, 09:22 »

Цитировать
Приведенная тобой ссылка относится к новому еще разрабатываемому стандарту С++0x.
конечно, с++0х еще разрабатываемый, но для меня он основным, уже как пол года. в версии gcc-4.5 появится поддержка лямбда, вот тогда, он будет реализован на 97%.
а про то, древнее КС auto, я не подумал, из-за того, что оно ваще не понятно для чего существует. так как модель памяти по умолчанию автоматическая.

Цитировать
Если кто знает, то прошу поделиться.
по приведенной мною ссылке, внизу страницы, куча доки на эту тему.
Записан
Геннадий Пастухов
Гость
« Ответ #14 : Январь 08, 2010, 13:27 »

Общее правило стандартное С++-ное: автоматические объекты удалятся сами, созданные вручную через new необходимо удалять самому.

Во-первых, что такое "автоматические обьекты"? Во-вторых не вижу связи, что выделенное через new нужно удалять самому. Qt наглядно демонстрирует, что это не так. К примеру QObject сам удалит дочерние обьекты, а QSharedDataPointer сам удалит руками выделенный экземпляр QSharedData.

Про объекты уже написали, а про создание/удаление в любом варианте С++ лучше не заниматься самодеятельностью, а всегда автоматически делать: создал объект через new - удали его через delete. Лень этим заниматься - используй auto_ptr. Лень самому заниматься обработкой памяти - используй только автоматические объекты. Но никогда не оставляй ничего не самотек, иначе получишь как раз утёк памяти Улыбающийся В программе, которая 1 раз запускается и тут же завершается - это, возможно, роли не сыграет, но если она будет работать хотя бы несколько минут - последствия будут самыми плачевными. Контроль за памятью убережёт тебя от кучи странных ошибок, поэтому сразу привыкай следить за ней самым тщательным образом.
Записан
Страниц: [1] 2 3 ... 10   Вверх
  Печать  
 
Перейти в:  


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