【问题标题】:Constructor dependency injection: unique_ptr + move vs shared_ptr构造函数依赖注入:unique_ptr + move vs shared_ptr
【发布时间】:2017-03-15 13:08:23
【问题描述】:

假设我们有这样的东西:

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

【问题讨论】:

  • 但是传递副本无效,所以我们需要移动到指针。 或者你让 Complex 和 Part 可移动?
  • 复杂 - 只是一个复杂的、长寿的对象。但目前我不打算实施“五规则”。
  • 如果它可以解决您的问题,也不是吗?无论如何:智能指针代表某种所有权,所以答案似乎很简单:如果 p1/p2/p3 不是 shared,不要使用 shared_ptr?
  • 我同意,但与创建 shared_ptr 相比,创建和移动 unique_ptr 的效果可能较差或有一些副作用?
  • @silent_coder 复制shared_ptr 涉及原子增量,销毁shared_ptr 涉及原子减量。移动unique_ptr 涉及两个指针分配,销毁一个空的unique_ptr 是一个空操作。你觉得哪个更快? ;-)

标签: c++ c++11 c++14 shared-ptr unique-ptr


【解决方案1】:

最好的解决方案是让Part 类型的移动成本低廉,然后将它们移入。但是,如果这不是一个选项,您将不得不求助于动态管理它们。

正如您所说,Complex 拥有这些部件,因此它应该将它们作为std::uniqe_ptr<Part> 接受并将这些指针移入自身。移动 std::unique_ptr 非常便宜:它可能只涉及两个指针分配。

另一方面,使用std::shared_ptr 和复制涉及不必要的原子增量(用于创建副本)和减量(用于销毁原始文件)。对于当今的高速缓存多核处理器而言,原子操作肯定远非便宜。

因此,只要坚持代码的预期语义(唯一所有权,惯用语为 std::unique_ptr),您将获得良好的性能作为奖励。

【讨论】:

  • @GeorgeAl 一个将目标指向指针对象,一个将源指向 null。否则,source 的析构函数不会知道它是空的,并且会释放指针。
猜你喜欢
  • 2011-02-02
  • 2021-08-28
  • 2019-04-20
  • 1970-01-01
  • 1970-01-01
  • 2018-06-17
  • 1970-01-01
  • 2023-04-04
相关资源
最近更新 更多