【问题标题】:How to push_back existing objects to a vector of shared pointers?如何将现有对象 push_back 到共享指针向量?
【发布时间】:2018-07-02 09:37:30
【问题描述】:

使用原始指针,我可以创建一个指针向量和 push_back 地址,如下所示:

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

如果我改为使用共享指针向量:

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

...我如何 push_back 地址?

据我了解,std::shared_ptr::reset 用于将现有对象的地址分配给智能指针。是否需要先创建一个临时指针,调用reset,然后push_back?

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

【问题讨论】:

  • 为什么不 push_back(make_shared(objEntity)) ?
  • 当你使用 push_back 时,会调用一个复制构造函数。
  • @Clonk 仅当您将左值引用传递给它时。
  • 如果你想让它执行然后更喜欢 Boost.PolyCollection 到智能指针向量(它通常会获胜,因为它会减少内存碎片),如果你因为任何原因不能使用 boost 然后使用 unique_ptr 的向量摆脱 shared_ptr 的双重间接和其他开销。

标签: c++ smart-pointers stdvector


【解决方案1】:

您可以使用emplace_back 从现有指针构造一个新的共享指针:

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

您也可以使用push_back 来构造带有make_shared 的对象。

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

没有办法安全地添加现有对象(不是作为指针创建的)。您可以添加现有指针,或在创建共享指针时制作副本。

如果添加现有对象的地址,则会尝试两次释放内存,因为共享指针的析构函数会破坏该对象:

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

【讨论】:

  • 我会接受这个作为答案,因为它向我解释了为什么我不应该做我想做的事情。
【解决方案2】:

创建智能指针时,最好使用它们的std::make_* 函数。 vector::push_back 为右值引用重载,像这样调用它

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

因此将通过移动您传入的std::shared_ptr 在向量中构造一个元素,因此不会因为在此处修改智能指针的控制块而影响性能。另请注意,vector::emplace_back 不能与 std::make_shared 一起使用,而只能与原始指针一起使用,为了异常处理和简洁性,应避免这种情况(传递原始指针需要手动创建 Entity 实例堆)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    相关资源
    最近更新 更多