我应该使用c++ 11的emplace_back指针容器吗?

Should I use C++11 emplace_back with pointers containers?

本文关键字:指针 back emplace c++ 我应该      更新时间:2023-10-16

有一个通常的基础->派生层次结构,如:

class Fruit { ... };
class Pear : Fruit { ... };
class Tomato : Fruit { ... };
std::vector<Fruit*> m_fruits;

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

std::vector::emplace_back( new Pear() );
std::vector::emplace_back( new Tomato() );

不要使用原始指针,像这样使用std::unique_ptr:

std::vector<std::unique_ptr<Fruit>> m_fruits;

由于您不能复制构建std::unique_ptr,您必须使用emplace_back(尽管您可以使用push_backstd::move)。

s

<> <>之前m_fruits。emplace_back(新梨());m_fruits。emplace_back番茄()(新);

编辑:

如果std::vector需要并且没有重新分配内存,那么使用std::vector<std::unique_ptr<T>>::emplace_backnew可能会泄漏,我推荐的方法(直到c++ 14引入std::make_unique)是像这样使用push_back:

m_fruits.push_back(std::unique_ptr<Fruit>(new Pear()));
m_fruits.push_back(std::unique_ptr<Fruit>(new Tomato()));

或者使用std::make_unique:

m_fruits.push_back(std::make_unique<Pear>());
m_fruits.push_back(std::make_unique<Tomato>());

指针是标量类型,因此是文字类型,因此copy、move和emplace构造(来自左值或右值)都是等效的,并且通常会编译成相同的代码(标量复制)。push_back更清楚地表明你正在执行标量复制,而emplace_back应该保留给调用非复制或移动构造函数(例如转换或多参数构造函数)的放置构造。

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