crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в Удаление объекта из QList
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
ssoft Дата 14.1.2013, 7:12
 
Цитата(quarz @ 11.1.2013, 19:57) *
Когда ты создаешь объект (TObject здесь может быть любым типом),
TObject* pObj = new TObject();

он физически размещается в оперативной памяти, а (uint)pObj хранит адрес памяти, по которому разместился объект. Если тебе (вдруг) нужен именно список самих объектов, то так и пишешь:
QList<TObject> myObjectList;
TObject* pObj = new TObject();
myObjectList.append(*pObj);     // необходимо разыменование указателя


Во первых, у человека производный от Widget, который имеет запрет на конструктор копирования, поэтому этот номер даже не скомпилируется.
Во вторых, объект, созданный через new, нигде не удаляется, следовательно - утечки памяти.

Цитата(quarz @ 11.1.2013, 19:57) *
А если же тебе нужен список Указателей на объекты, то:
QList<TObject*> myPtrObjectList;
TObject* pObj = new TObject();
myPtrObjectList.append(pObj);

и здесь удалять тоже ничего не нужно: переменная pObj исчезнет, когда будет покинута ее область видимости, а сам объект *pObj, тебе нужно будет удалить перед удалением его из списка:
delete myPtrObjectList[i];
myPtrObjectList.removeAt(i);


В третих, удаление самого объекта и есть то, что всегда нужно удалять, поэтому непонятна фраза "и здесь удалять тоже ничего не нужно".
quarz Дата 11.1.2013, 18:57
  QMainWindow надо обрести понимание указателей, т.к. это полный бред:
Цитата(QMainWindow @ 10.1.2013, 10:28) *
Ну да, это я ошибся. Ну понятно, имелось ввиду создать виджет, положить ЕГО в список, а то, что осталось удалить.

Когда ты создаешь объект (TObject здесь может быть любым типом),
TObject* pObj = new TObject();

он физически размещается в оперативной памяти, а (uint)pObj хранит адрес памяти, по которому разместился объект. Если тебе (вдруг) нужен именно список самих объектов, то так и пишешь:
QList<TObject> myObjectList;
TObject* pObj = new TObject();
myObjectList.append(*pObj);     // необходимо разыменование указателя


А если же тебе нужен список Указателей на объекты, то:
QList<TObject*> myPtrObjectList;
TObject* pObj = new TObject();
myPtrObjectList.append(pObj);

и здесь удалять тоже ничего не нужно: переменная pObj исчезнет, когда будет покинута ее область видимости, а сам объект *pObj, тебе нужно будет удалить перед удалением его из списка:
delete myPtrObjectList[i];
myPtrObjectList.removeAt(i);
ssoft Дата 10.1.2013, 11:36
  Рекомендую использовать умные указатели, тогда вообще не нужно заморачиваться с удалениями, код будет понятнее и не будет приводить к утечкам памяти, например, в случае исключений.

Что-то вроде

    typedef QSharedPointer< MyWidget > Widget;
    myWidgetList.append( Widget( new MyWidget ) ); // добавление

    ...

    myWidgetList.removeAt( i ); // удаление

    ...

    myWidgetList.clear(); // удаление всех сразу
QMainWindow Дата 10.1.2013, 9:28
 
Цитата(iReset @ 10.1.2013, 10:15) *
Уже неправильно. В QList ты сохранил только указатель на виджет, за сам виджет отвечаешь ты, он не сохраняется в myWidgetList. Следовательно, после того как ты удалил виджет myWidget, указатель в myWidgetList остался, но стал указывать на нераспределённую память, в которой ранее был твой виджет. Формально его уже нет и что там по этому участку памяти, неизвестно. delete тут делать не надо.
Ну да, это я ошибся. Ну понятно, имелось ввиду создать виджет, положить ЕГО в список, а то, что осталось удалить.

Цитата(iReset @ 10.1.2013, 10:15) *
delete myWidgetList.at(i);
Это удалит сам виджет. А removeAt удалит только указатель на виджет из QList. Т.е. тебе нужно сделать что-то вроде
delete myWidgetList.at(i);
myWidgetList.removeAt(i);

Спасибо.
iReset Дата 10.1.2013, 9:15
 
Цитата(QMainWindow @ 9.1.2013, 22:27) *
Есть код:
MyWidget *myWidget = new MyWidget(this);
    myWidgetList.append(myWidget);
    delete myWidget;
Уже неправильно. В QList ты сохранил только указатель на виджет, за сам виджет отвечаешь ты, он не сохраняется в myWidgetList. Следовательно, после того как ты удалил виджет myWidget, указатель в myWidgetList остался, но стал указывать на нераспределённую память, в которой ранее был твой виджет. Формально его уже нет и что там по этому участку памяти, неизвестно. delete тут делать не надо.

Цитата(QMainWindow @ 9.1.2013, 22:27) *
...как-нибудь так:
myWidgetList.first().~MyWidget();
Так вообще никогда делать не надо! Вызов деструктора без удаления самого объекта может привести к непредсказуемым результатам.
Если делал new, то для удаления виджета делай delete, т.е. так:
delete myWidgetList.at(i);
Это удалит сам виджет. А removeAt удалит только указатель на виджет из QList. Т.е. тебе нужно сделать что-то вроде
delete myWidgetList.at(i);
myWidgetList.removeAt(i);
QMainWindow Дата 9.1.2013, 21:27
  Вечер добрый.
Есть код:
MyWidget *myWidget = new MyWidget(this);
    myWidgetList.append(myWidget);
    delete myWidget;
Создал некоторый виджет, положил его для удобства в QList, удалил, чтобы не занимал место. Далее этот список попользовал и пришло время удалить из него этот виджет.
myWidgetList.removeAt(i);
Тут вопрос: чтобы этот виджет удалился и из списка, и из памяти, достаточно этой строчки? Или нужно как-нибудь так:
myWidgetList.first().~MyWidget();
myWidgetList.removeAt(i);


PS Ну понятно, что i - это порядковый номер моего виджета, необязательно первый.
Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 16.4.2024, 11:48