C++ 构造函数依赖注入:惟一的ptr+;移动与共享\u ptr

C++ 构造函数依赖注入:惟一的ptr+;移动与共享\u ptr,c++,c++11,c++14,shared-ptr,unique-ptr,C++,C++11,C++14,Shared Ptr,Unique Ptr,让我们假设我们有这样的东西: struct Complex{ Complex(Part1 p1, Part2 p2, Part3 p3) } Part1 p1; Part2 p2; Part3 p3; 然而,传递副本是无效的,所以我们需要转移到指针。问题是使用哪种类型-unique\u ptr或shared\u ptr 乍一看,由于Complex是p1、p2、p3的真正所有者,因此unique\u ptr似乎更好;但是,由于无法复制,我们需要使用std::move 所以我的问题是

让我们假设我们有这样的东西:

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

Part1 p1; 
Part2 p2;
Part3 p3; 
然而,传递副本是无效的,所以我们需要转移到指针。问题是使用哪种类型-
unique\u ptr
shared\u ptr

乍一看,由于
Complex
p1、p2、p3
的真正所有者,因此
unique\u ptr
似乎更好;但是,由于无法复制,我们需要使用
std::move


所以我的问题是-对于这种情况,什么是更好的方法,从
部分
中创建
唯一的\u ptr
,然后在
复杂
的构造函数中使用
移动
,或者从一开始就创建
shared\u ptr
,然后改用
shared\u ptr

最好的解决方案是使
零件
类型移动起来便宜,并将其移入。然而,如果这不是一个选项,您将不得不求助于动态管理它们

正如您所说,
Complex
拥有这些部分,因此它应该将它们作为
std::uniqe\u ptr
接受,并将这些指针移动到自身中。移动
std::unique_ptr
非常便宜:它可能只涉及两个指针分配

另一方面,使用
std::shared_ptr
和复制,这涉及到不必要的原子增量(用于创建副本)和减量(用于销毁原件)。对于今天的高速缓存密集型多核处理器来说,原子操作显然远不便宜


因此,只要坚持您的代码的预期语义(唯一所有权,这是由
std::unique\u ptr
习惯表达的),您将获得良好的性能作为奖励。

但是传递副本无效,因此我们需要转向指针。或者你让复杂和部分可移动?复杂-只是一个复杂的,长期存在的对象。但就目前而言,我不打算实施“五人法则”。如果这能解决你的问题,我也不打算?无论如何:智能指针代表某种所有权,因此答案似乎很简单:如果p1/p2/p3没有共享,不要使用共享的ptr?我同意,但创建和移动唯一的ptr可能比创建共享的ptr效果差,或者有一些副作用?@沉默的ptr复制
共享的ptr
涉及原子增量,销毁
共享的\u ptr
涉及原子减量。移动一个
unique_ptr
涉及两个指针赋值,销毁一个空的
unique_ptr
是不可操作的。您认为哪个更快?;-)@GeorgeAl一个用于将目标指向pointee,另一个用于将源指向null。否则,source的析构函数将不知道它是空的,并将取消分配指针对象。