如何将现有对象push_back到共享指针向量?

Nat*_*.M. 0 c++ smart-pointers stdvector

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

Entity objEntity;
std::vector<Entity*> Entities;
Entities.push_back(&objEntity);
Run Code Online (Sandbox Code Playgroud)

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

std::vector<std::shared_ptr<Entity>> Entities;
Run Code Online (Sandbox Code Playgroud)

...如何推送地址?

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

std::shared_ptr<Entity> temp;
temp.reset(&objEntity);
Entities.push_back(temp);
Run Code Online (Sandbox Code Playgroud)

lub*_*bgr 6

在创建智能指针时,最好使用它们的std::make_*功能.vector::push_back为rvalue引用重载,像这样调用它

Entities.push_back(std::make_shared<Entity>());
Run Code Online (Sandbox Code Playgroud)

因此,通过移动std::shared_ptr您传入的内容,将在向量中构造一个元素,因此在此处不会因修改智能指针的控制块而导致性能下降.还要注意,vector::emplace_back不能使用std::make_shared但只能使用原始指针,为了处理异常和简洁,应该避免使用(传递原始指针需要Entity在堆上手动创建实例).


vll*_*vll 5

您可以使用emplace_back构造新的共享指针:

Entity* entity = new Entity;
std::vector<std::shared_ptr<Entity>> Entities;
Entities.emplace_back(entity);
Run Code Online (Sandbox Code Playgroud)

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

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??
Run Code Online (Sandbox Code Playgroud)

要避免这种情况,您需要new在创建共享指针时使用构造对象或进行复制.

  • 这里需要明确的是,第二个例子是"错误的".此外,最好将实体实例创建为std :: shared_ptr <Entity>,以确保在向量调整异常时清除它.下面的make_shared示例也很好,但我们并不总是想使用make_shared. (2认同)