让我们假设我们有这样的内容:
struct Complex{
Complex(Part1 p1, Part2 p2, Part3 p3)
}
Part1 p1;
Part2 p2;
Part3 p3;
但是传递副本是无效的,所以我们需要转向指针。问题是使用什么类型—unique_ptr
或shared_ptr
乍一看,由于Complex
是p1, p2, p3
的真正所有者,因此unique_ptr
似乎更好;然而,由于它不能被复制,我们需要使用std::move
。
我的问题是—对于这种情况,更好的方法是在Part
中创建unique_ptr
,然后在Complex
的构造函数中使用move
,还是从一开始创建shared_ptr
并使用shared_ptr
?
最好的解决方案是使Part
类型的移动成本更低,并将它们移动进来。但是,如果这不是一个选项,您将不得不诉诸于动态管理它们。
正如你所说,Complex
拥有这些部分,所以它应该接受它们作为std::uniqe_ptr<Part>
,并将这些指针移动到自己身上。移动std::unique_ptr
非常便宜:它可能只涉及两次指针赋值。
std::shared_ptr
和复制涉及不必要的原子递增(用于创建副本)和递减(用于销毁原始)。原子操作对于今天缓存量大的多核处理器来说当然不便宜。
因此,只要坚持代码的预期语义(唯一所有权,这是由std::unique_ptr
习惯表达的),您将获得良好的性能作为奖励。