Как push_back существующих объектов к вектору общих указателей? - PullRequest
0 голосов
/ 02 июля 2018

Используя необработанные указатели, я могу создать вектор указателей и адресов push_back следующим образом:

Entity objEntity;
std::vector<Entity*> Entities;
Entities.push_back(&objEntity);

Если вместо этого я использую вектор общих указателей:

std::vector<std::shared_ptr<Entity>> Entities;

... как я могу отправить обратно адреса?

Насколько я понимаю, std :: shared_ptr :: reset используется для назначения адреса существующего объекта интеллектуальному указателю. Нужно ли сначала создать временный указатель, сбросить вызов, а затем push_back?

std::shared_ptr<Entity> temp;
temp.reset(&objEntity);
Entities.push_back(temp);

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

При создании умных указателей лучше всего использовать их std::make_* функции. vector::push_back перегружен для ссылок rvalue, вызывая его следующим образом

Entities.push_back(std::make_shared<Entity>());

, следовательно, создаст элемент в векторе, переместив std::shared_ptr, который вы передали, следовательно, никакого снижения производительности из-за изменения здесь управляющего блока интеллектуального указателя. Также обратите внимание, что vector::emplace_back нельзя использовать с std::make_shared, а только с необработанным указателем, чего следует избегать ради обработки исключений и краткости (передача необработанного указателя требует ручного создания экземпляра Entity в куча).

0 голосов
/ 02 июля 2018

Вы можете использовать emplace_back для создания нового общего указателя:

Entity* entity = new Entity;
std::vector<std::shared_ptr<Entity>> Entities;
Entities.emplace_back(entity);

Если вы добавите адрес существующего объекта, вы попытаетесь дважды освободить память, потому что деструктор общего указателя уничтожает объект:

Entity entity;
std::vector<std::shared_ptr<Entity>> Entities;
Entities.emplace_back(&entity);
// What happens when entity and shared pointer both go out of scope??

Чтобы избежать этого, вам нужно либо создать объект с помощью new, либо сделать копию при создании общего указателя.

...