传递共享指针作为参数

如果我声明一个包装在共享指针中的对象:

std::shared_ptr<myClass> myClassObject(new myClass()); 

那么我想把它作为一个parameter passing给一个方法:

 DoSomething(myClassObject); //the called method void DoSomething(std::shared_ptr<myClass> arg1) { arg1->someField = 4; } 

以上是否简单地增加了shared_pt的引用计数,一切都很酷? 还是会留下一个晃来晃去的指针?

你还是应该这样做吗?

 DoSomething(myClassObject.Get()); void DoSomething(std::shared_ptr<myClass>* arg1) { (*arg1)->someField = 4; } 

我认为第二种方法可能更有效率,因为它只需要复制1个地址(而不是整个智能指针),但是第一种方式看起来更具可读性,我不希望推行性能限制。 我只是想确保没有什么危险的事情。

谢谢。

我想传递一个函数的共享指针。 你能帮我吗?

当然,我可以帮你。 我假设你对C ++中的所有权语义有一些了解。 真的吗?

是的,我对这个问题很合适。

好。

好吧,我只能想到采取shared_ptr参数的两个理由:

  1. 该function要分享对象的所有权;
  2. 该函数执行一些专门在shared_ptr的操作。

你对哪一个感兴趣?

我正在寻找一个普遍的答案,所以我实际上对两个都感兴趣。 不过,我很好奇你的意思。

这样的函数的例子包括std::static_pointer_cast ,自定义比较器或谓词。 例如,如果您需要从vector中find所有唯一的shared_ptr,则需要这样的谓词。

啊,这个函数实际上需要操纵智能指针本身。

究竟。

在这种情况下,我认为我们应该通过参考。

是。 如果它不改变指针,你想通过const引用传递。 没有必要复制,因为你不需要共享所有权。 这是另一种情况。

好的,我知道了。 我们来谈谈另一种情况。

你分享所有权的那个? 好。 你如何与shared_ptr共享所有权?

通过复制它。

那么这个函数需要复制一个shared_ptr ,是否正确?

明显。 所以我通过引用const传递它并复制到一个局部variables?

不,这是一个悲观。 如果通过引用传递,则该function将别无select,只能手动进行复制。 如果按值传递,编译器会select副本和移动之间的最佳select并自动执行。 所以,按价值传递。

好点子。 我必须记得更多的时候是“ 想要速度?超值 ”。

等等,如果函数将shared_ptr存储在成员variables中,例如? 这不会造成多余的副本吗?

该函数可以简单地将shared_ptr参数移动到其存储中。 移动一个shared_ptr是很便宜的,因为它不会改变任何引用计数。

啊,好主意。

但是我想到了第三种情况:如果你不想操纵shared_ptr ,又不想共享所有权呢?

在这种情况下, shared_ptr与函数完全无关。 如果你想操纵指针,拿指尖,让调用者select他们想要的所有权语义。

我应该参照还是通过价值来指责?

通常的规则适用。 智能指针不会改变任何东西。

如果我要复制,按照价值传递,如果我想避免复制,请按照参考传递。

对。

嗯。 我想你忘了另一个场景。 如果我想分享所有权,但仅仅依赖于某种条件呢?

啊,一个有趣的边缘情况。 我不期望经常发生。 但是当它发生的时候,你可以通过价值传递,如果你不需要,可以忽略副本,或者通过引用传递,如果你需要的话可以复制。

第一个选项我冒了一个多余的副本,并在第二个选项中失去了一个潜在的举措。 我不能吃这个蛋糕吗?

如果你处于一个非常重要的情况,你可以提供两个重载,一个取const Lvalue引用,另一个取右值引用。 一个副本,另一个副本。 完美转发function模板是另一种select。

我认为这涵盖了所有可能的情况。 非常感谢你。

我认为人们不必要地害怕使用原始指针作为函数参数。 如果函数不会存储指针或影响其生存期,则原始指针也可以正常工作,并表示最小公分母。 例如,考虑如何将unique_ptr传递unique_ptr shared_ptr作为参数的函数,无论是通过值还是通过const引用?

 void DoSomething(myClass * p); DoSomething(myClass_shared_ptr.get()); DoSomething(myClass_unique_ptr.get()); 

作为函数参数的原始指针不会阻止您在调用代码中使用智能指针,而这些指针真的很重要。

是的,关于shared_ptr <>的整个想法是多个实例可以保存相同的原始指针,并且只有在shared_ptr <>的最后一个实例被销毁时才会释放底层内存。

我会避免一个指向shared_ptr <>的指针,因为这是你正在处理的raw_pointers再次失败的目的。

在你的第一个例子中传递值是安全的,但有一个更好的习惯用法。 尽可能传递const引用 – 即使在处理智能指针时,我也会说是。 你的第二个例子不是完全破碎,但它是非常!??? 。 愚蠢的是,没有完成任何事情,击败了智能指针的一部分,当你试图解引用和修改东西时,会让你陷入一个错误的痛苦世界。