构造函数依赖注入:unique_ptr + move vs shared_ptr

Constructor dependency injection: unique_ptr + move vs shared_ptr

本文关键字:ptr vs shared move unique 函数依赖 注入      更新时间:2023-10-16

让我们假设我们有这样的内容:

struct Complex{
    Complex(Part1 p1, Part2 p2, Part3 p3)
}
Part1 p1; 
Part2 p2;
Part3 p3; 

但是传递副本是无效的,所以我们需要转向指针。问题是使用什么类型—unique_ptrshared_ptr

乍一看,由于Complexp1, 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习惯表达的),您将获得良好的性能作为奖励。