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

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

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: qDeleteAll - глупый и опасный метод!  (Прочитано 40072 раз)
frostyland
Гость
« : Январь 07, 2011, 17:02 »

Код
C++ (Qt)
void qDeleteAll ( ForwardIterator begin, ForwardIterator end )
void qDeleteAll ( const Container & c )
Deletes all the items in the range [begin, end) using the C++ delete operator. The item type must be a pointer type ...
И примером:
Код
C++ (Qt)
QList<Employee *> list;
list.append(new Employee("Blackpool", "Stephen"));
list.append(new Employee("Twist", "Oliver"));
 
qDeleteAll(list.begin(), list.end());
list.clear();

Зачем нужен метод, чистящий память, но оставляющий в контейнере невалидные указатели?
Это абсолютно глупо! Нет ни одного случая, где бы эти указатели-хвосты могли бы понадобиться.
.clear() просто должно было быть там по умолчанию в реализации qDeleteAll.
Все равно приходится либо помнить об его вызове, либо писать свою над-функцию...
Совершенно непонятна такая стратегия  Непонимающий

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

Сообщений: 3880


Просмотр профиля WWW
« Ответ #1 : Январь 07, 2011, 17:30 »

>>.clear() просто должно было быть там по умолчанию в реализации qDeleteAll.
вот это точно глупость. У меня списке что? А в списке у меня список указателей на объекты, которые где-либо я использую. Если мне нужно очистить список, то это не значит, что мне нужно прибить эти объекты.

Записан

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

Сообщений: 2901



Просмотр профиля WWW
« Ответ #2 : Январь 07, 2011, 17:31 »

А как ты представляешь себе вызов clear() внутри qDeleteAll?
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #3 : Январь 07, 2011, 17:33 »

2 lit-uriy: Как понял, автор имел ввиду вызов clear() внутри qDeleteAll
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #4 : Январь 07, 2011, 17:36 »

>> Как понял, автор имел ввиду вызов clear() внутри qDeleteAll
 ну так вполне реально было бы реализовать для void qDeleteAll ( const Container & c )
т.к. контейнер известен:
Код
C++ (Qt)
void qDeleteAll ( const Container & c )
{
   ...
 
   c.clear();
}
Записан

Юра.
brankovic
Гость
« Ответ #5 : Январь 07, 2011, 17:50 »

Зачем нужен метод, чистящий память, но оставляющий в контейнере невалидные указатели?

Чтобы не очищать сам контейнер, конечно:

Код
C++ (Qt)
Vector <Data*> v;
v.resize (0, 99);
for (int j = 0; j < 77; ++j)
{
 for (int i = 0; i < 99; ++i)
   v [i] = new Data (i, j);
 
 ... //using v
 
 qDeleteAll (v);
}
« Последнее редактирование: Январь 07, 2011, 23:09 от brankovic » Записан
ufna
Гость
« Ответ #6 : Январь 07, 2011, 17:56 »

Контейнер - это контейнер, а данные - это данные. Удаление данных это одно, очистка контейнера - другое, и не стоит имхо в любом из вариантов "удалить и то и то".
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Январь 07, 2011, 19:29 »

>> Как понял, автор имел ввиду вызов clear() внутри qDeleteAll
 ну так вполне реально было бы реализовать для void qDeleteAll ( const Container & c )
т.к. контейнер известен:
Код
C++ (Qt)
void qDeleteAll ( const Container & c )
{
   ...
 
   c.clear();
}
Метод clear не const. Реализовать конечно реально, но не по уму. Метод/ф-ция должна делать то о чем их просили - и ничего больше. Много раз видел такое
Код
C++ (Qt)
#define DELETE_PTR(p)  (delete(p); p = NULL;)
 
Но не пытался критиковать delete  Улыбающийся
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #8 : Январь 08, 2011, 05:19 »

> Метод clear не const.

+1
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
SABROG
Гость
« Ответ #9 : Январь 08, 2011, 10:46 »

Я иногда храню в контейнерах QSharedPointer'ы вместо оригинального указателя и мне достаточно метода clear() у контейнера для одновременной очистки и освобождения памяти.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #10 : Январь 08, 2011, 11:34 »

>>Метод clear не const.
ну это сейчас не const. А если совершенствовать функцию qDeleteAll, то можно и убрать в ней это ограничение.
Записан

Юра.
frostyland
Гость
« Ответ #11 : Январь 26, 2011, 13:54 »

>>.clear() просто должно было быть там по умолчанию в реализации qDeleteAll.
вот это точно глупость. У меня списке что? А в списке у меня список указателей на объекты, которые где-либо я использую. Если мне нужно очистить список, то это не значит, что мне нужно прибить эти объекты.
Долго гулял )))

>> Если мне нужно очистить список, то это не значит, что мне нужно прибить эти объекты.
Верно!
То есть, Вам нужно очистить список, Вы делаете <список>.clear().
А здесь с тобчность до наоборот в qDeleteAll, вдумайтесь.
Он прибивает объекты, так? А указатели - оставляет. Идиотизм.
ТО есть в контейнере по прежнему остается X указателей, которые никуда уже не указывают.

============================
Во всяком случае, приведите мне пример, когда после
qDeleteAll(someContainer) кому либо захотелось поиграться с указателями в someContainer.
Ну или примеры в студию )))

« Последнее редактирование: Январь 26, 2011, 14:00 от frostyland » Записан
SASA
Гость
« Ответ #12 : Январь 26, 2011, 14:11 »

frostyland, я думаю, что Вы не правы в своей категоричности.
Функция qDeleteAll не является методом контейнеров. Она написана для удобства. qt - очень универсальный фреймворк. Из того, что Вы не можете придумать случай, когда qDeleteAll используется без clear, не следует то, что таких случаев нет. Если вам удобней пользоваться другой функцией, то напишите свою её
Код:
void myDeleteAll ( const Container & c )
{
    qDeleteAll(c);
    c.clear();
}

З.Ы. Я сам в 90% случаев использую qDeleteAll вместе с clear.
Записан
frostyland
Гость
« Ответ #13 : Январь 26, 2011, 14:19 »

Функция qDeleteAll не является методом контейнеров. Она написана для удобства.
Там ни слова про контейнеры, верно?
Код
C++ (Qt)
void qDeleteAll ( const Container & c )
This is an overloaded function.
This is the same as qDeleteAll(c.begin(), c.end()).
Лишь про интерфейс, безумно напоминающий интерфейс контейнера.
Да ладно, холивор. )))
« Последнее редактирование: Январь 26, 2011, 14:24 от frostyland » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Январь 26, 2011, 14:28 »

Во всяком случае, приведите мне пример, когда после
qDeleteAll(someContainer) кому либо захотелось поиграться с указателями в someContainer.

Код
C++ (Qt)
struct MyData {
...
~MyData( void )  {}
 
int mType;
QString * mText;
...
};
 
void Data2Storage( QList<MyData> & src, QVector <QString *> & textStorage )
{
qDeleteAll(textStorage);
size_t i, limit = src.size();
textStorage.resize(limit);
for (i = 0; i < limit; ++i)
 textStorage[i] = src[i].mText;
}
 
« Последнее редактирование: Январь 26, 2011, 14:30 от Igors » Записан
Страниц: [1] 2 3 4   Вверх
  Печать  
 
Перейти в:  


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