我应该使用带有指针包含的C++ 11\templace_back吗?

Zhe*_*hen 19 c++ smart-pointers c++11

拥有通常的Base - > Derived层次结构,如:

class Fruit { ... };
class Pear : Fruit { ... };
class Tomato : Fruit { ... };

std::vector<Fruit*> m_fruits;
Run Code Online (Sandbox Code Playgroud)

是否有意义(例如:它有更好的性能)使用emplace_back而不是push_back?

std::vector::emplace_back( new Pear() );
std::vector::emplace_back( new Tomato() );
Run Code Online (Sandbox Code Playgroud)

Snp*_*nps 23

不要使用原始指针,使用std::unique_ptr如下:

std::vector<std::unique_ptr<Fruit>> m_fruits;
Run Code Online (Sandbox Code Playgroud)

正如你不能复制构造std::unique_ptr必须使用emplace_back(尽管你可以用push_backstd::move).

__PRE__

编辑:

因为看起来如果需要使用std::vector<std::unique_ptr<T>>::emplace_back并且new可能泄漏std::vector并且无法重新分配内存,我推荐的方法(直到C++ 14介绍std::make_unique)是这样使用push_back:

m_fruits.emplace_back(new Pear());
m_fruits.emplace_back(new Tomato());

或使用std::make_unique:

m_fruits.push_back(std::unique_ptr<Fruit>(new Pear));
m_fruits.push_back(std::unique_ptr<Fruit>(new Tomato));
Run Code Online (Sandbox Code Playgroud)


eca*_*mur 17

指针是标量类型,因此是文字类型,因此复制,移动和安置构造(从左值或右值)都是等效的,并且通常会编译为相同的代码(标量副本). push_back更清楚的是你正在执行标量副本,而emplace_back应该保留用于调用非副本或移动构造函数的emplace构造(例如转换或多参数构造函数).

如果你的向量应该保持std::unique_ptr<Fruit>而不是原始指针(以防止内存泄漏),那么因为你正在调用转换构造函数emplace_back会更正确.但是,如果扩展向量失败,仍然会泄漏,所以在这种情况下你应该使用push_back(make_unique<Pear>())等.

  • @Zhen:可能会出现这种情况,但事实并非如此.`emplace_back(new T())`可以*泄漏*,而`push_back(make_unique <T>())`不能.是的,监督中缺少`make_unique`,你可以在网上找到实现. (3认同)
  • 在C ++ 14中添加了`std :: make_unique()`。 (2认同)