有一个通常的Base -> Derived层次结构,如。
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() );
指针是标量类型,因此是文字类型,所以复制、移动和置换构造(从lvalue或rvalue)都是等价的,通常会编译成相同的代码(标量拷贝)。 push_back
更清楚的是,你正在执行一个标量拷贝,而 emplace_back
应该保留给调用非复制或移动构造函数的emplace构造(例如converting或多参数构造函数)。
如果你的向量应该持有 std::unique_ptr<Fruit>
而不是原始指针(以防止内存泄漏),那么因为你调用了一个转换构造函数 emplace_back
会更正确。 然而,如果扩展向量失败,还是会泄露,所以在这种情况下,你应该使用 push_back(make_unique<Pear>())
等。
不要使用原始指针,使用 std::unique_ptr
像这样。
std::vector<std::unique_ptr<Fruit>> m_fruits;
由于你不能复制构建一个 std::unique_ptr
你必须使用 emplace_back
(尽管你可以使用 push_back
与 std::move
).
m_fruits.emplace_back(new Pear());m_fruits.emplace_back(new Tomato())。
编辑。
看来,使用 std::vector<std::unique_ptr<T>>::emplace_back
和 new
泄漏,如果 std::vector
需要而未能重新分配内存,我推荐的方法(直到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>());