我想将共享指针传递给函数。你能帮我解决这个问题吗?
当然,我可以帮你。我假设您对 C++ 中的所有权语义有一定的了解。真的吗?
是的,我对这个主题相当满意。
好的。
好吧,我只能想到两个理由来shared_ptr
争论:
- 该函数想要共享对象的所有权;
- 该函数做了一些专门作用于
shared_ptr
s 的操作。
你对哪一个感兴趣?
我正在寻找一个普遍的答案,所以我实际上对两者都感兴趣。不过,我很好奇您在案例 2 中的意思。
此类函数的示例包括std::static_pointer_cast
自定义比较器或谓词。例如,如果您需要从向量中找到所有唯一的 shared_ptr,则需要这样的谓词。
啊,当函数实际上需要操纵智能指针本身时。
确切地。
在那种情况下,我认为我们应该通过引用传递。
是的。如果它不改变指针,你想通过 const 引用传递。无需复制,因为您不需要共享所有权。那是另一种情况。
好的,我知道了。让我们谈谈另一种情况。
你分享所有权的那个?好的。你如何分享所有权shared_ptr
?
通过复制它。
那么该函数将需要复制 a shared_ptr
,对吗?
明显地。所以我通过对 const 的引用传递它并复制到局部变量?
不,这是一种悲观主义。如果通过引用传递,函数将别无选择,只能手动进行复制。如果它是按值传递的,编译器将在复制和移动之间选择最佳选择并自动执行。所以,按值传递。
好点子。我必须更频繁地记住“想要速度?传递价值。 ”文章。
等等,例如,如果函数将 存储shared_ptr
在成员变量中怎么办?这不会造成冗余副本吗?
该函数可以简单地将shared_ptr
参数移动到其存储中。移动 ashared_ptr
很便宜,因为它不会改变任何引用计数。
啊,好主意。
但我在考虑第三种情况:如果您不想操纵shared_ptr
, 也不想共享所有权怎么办?
在那种情况下,shared_ptr
与功能完全无关。如果您想操作指针对象,请获取指针对象,然后让调用者选择他们想要的所有权语义。
我应该通过引用还是按价值来获取指针?
通常的规则适用。智能指针不会改变任何东西。
如果我要复制,则按值传递,如果我想避免复制,则按引用传递。
正确的。
唔。我想你忘记了另一个场景。如果我想共享所有权,但仅取决于特定条件怎么办?
啊,一个有趣的边缘案例。我不希望这种情况经常发生。但是当它发生时,您可以通过值传递并在不需要时忽略副本,或者通过引用传递并在需要时制作副本。
我在第一个选项中冒着一个冗余副本的风险,而在第二个选项中失去了潜在的移动。我不能吃蛋糕也吃吗?
如果您处于真正重要的情况,您可以提供两个重载,一个采用 const 左值引用,另一个采用右值引用。一个复制,另一个移动。完美转发功能模板是另一种选择。
我认为这涵盖了所有可能的情况。非常感谢。