Russian Qt Forum

Qt => Вопросы новичков => Тема начата: evgenm27 от Июль 18, 2018, 17:29



Название: Как правильно освободить память в QHash?
Отправлено: evgenm27 от Июль 18, 2018, 17:29
Добрый день. Не могу разобраться с парой вопросов. Выделяю память под объект Client, потом этот указатель на объект помещаю в QHash с помощью insert.
Код:
QHash<int, Client*> Users;
Client *_client = new Client(var);
Users.insert(num, _client);
И потом когда мне нужно освободить память и удалить объект. Достаточно сделать
Код:
Users.erase(Users.find(num));
или нужно так:
Код:
Users.erase(Users.find(num));
delete _client;
И второй вопрос. В чем все таки разница между методами erase и remove в QHash? Буду благодарен за любые пояснения.


Название: Re: Как правильно освободить память в QHash?
Отправлено: Авварон от Июль 18, 2018, 19:03
Да, надо удалять руками, хэш просто хранит указатель на объект, а жизнью объекта должен управлять кто-то другой.

Используйте std::unordered_map и умные указатели (не получится, правда, с QString как ключ, но для int сойдет):

Код:
std::unordered_map<int, std::unique_ptr<Client>> Users;
auto client = std::make_unique<Client>();
Users.insert({num, std::move(client));
Users.erase(Users.find(num));

erase удаляет по итератору (который надо самому найти или как-то вычислить), а remove - по ключу.


Название: Re: Как правильно освободить память в QHash?
Отправлено: Alex Custov от Июль 18, 2018, 19:32
>Используйте std::unordered_map

Почему? Я не проверял, но думаю QHash+QSharedPointer подойдёт.


Название: Re: Как правильно освободить память в QHash?
Отправлено: Авварон от Июль 18, 2018, 19:56
Почему? Я не проверял, но думаю QHash+QSharedPointer подойдёт.

Подойдёт, но QSharedPointer - это накладные расходы в виде счётчика ссылок, который может быть и не нужен, если owner известен (хэшмапа).

std::unordered_map лучше тем что
1) умеет в movable-only типы (std::unique_ptr, std::thread)
2) умеет в emplace()
3) по нему удобнее итерироваться через range-for
4) для него не надо использовать qAsConst при итерации через range-for


Название: Re: Как правильно освободить память в QHash?
Отправлено: ViTech от Июль 19, 2018, 11:17
Тогда ещё немного оффтопа ).

Есть ли резон в Qt программах использовать QSharedPointer, когда есть std::shared_ptr?


Название: Re: Как правильно освободить память в QHash?
Отправлено: evgenm27 от Июль 19, 2018, 12:28
Спасибо, разобрался!


Название: Re: Как правильно освободить память в QHash?
Отправлено: Авварон от Июль 19, 2018, 13:03
Тогда ещё немного оффтопа ).

Есть ли резон в Qt программах использовать QSharedPointer, когда есть std::shared_ptr?

Нету, он строго хуже. Например, он умеет только статическую функцию-deleter, а функтор или лямбду уже нет


Название: Re: Как правильно освободить память в QHash?
Отправлено: Igors от Июль 19, 2018, 13:54
Цитировать
- Я люблю булки, плюшки, батоны и кекс! Я люблю хлеб, и торт, и пирожные, и пряники, хоть тульские, хоть медовые, хоть глазурованные. Сушки люблю тоже, и баранки, бублики, пирожки с мясом, повидлом, капустой и с рисом.

Я горячо люблю пельмени, и особенно ватрушки, если они свежие, но черствые тоже ничего. Можно овсяное печенье и ванильные сухари.

А еще я люблю кильки, сайру, судака в маринаде, бычки в томате, частик в собственном соку,икру баклажанную, кабачки ломтиками и жареную картошку.

Вареную колбасу люблю прямо безумно, ..