当一个函数接受一个shared_ptr(来自boost或c++ 11 STL)时,你是否传递它:

foo(const shared_ptr<T>& p) 或通过值:void foo(shared_ptr<T> p) ?

我更喜欢第一种方法,因为我怀疑它会更快。但这真的值得吗,还有其他问题吗?

你能否给出你选择的原因,或者如果是这样,为什么你认为这无关紧要。


当前回答

最近有一篇博客文章:https://medium.com/@vgasparyan1995/pass-by-value vs-pass-by-reference-to-const-c-f8944171e3ce

所以这个问题的答案是:Do(几乎)从不传递const shared_ptr<T>&。 只需传递底层类即可。

基本上,唯一合理的参数类型是:

shared_ptr<T> -修改并获得所有权 shared_ptr<const T> -不修改,拥有所有权 T& -修改,没有所有权 const T& -不修改,没有所有权 T -不修改,没有所有权,廉价复制

正如@accel在https://stackoverflow.com/a/26197326/1930508中指出的,Herb Sutter的建议是:

只有在不确定是否获得副本和共享所有权时,才使用const shared_ptr&作为参数

但有多少情况下你不确定?所以这种情况很少见

其他回答

最近有一篇博客文章:https://medium.com/@vgasparyan1995/pass-by-value vs-pass-by-reference-to-const-c-f8944171e3ce

所以这个问题的答案是:Do(几乎)从不传递const shared_ptr<T>&。 只需传递底层类即可。

基本上,唯一合理的参数类型是:

shared_ptr<T> -修改并获得所有权 shared_ptr<const T> -不修改,拥有所有权 T& -修改,没有所有权 const T& -不修改,没有所有权 T -不修改,没有所有权,廉价复制

正如@accel在https://stackoverflow.com/a/26197326/1930508中指出的,Herb Sutter的建议是:

只有在不确定是否获得副本和共享所有权时,才使用const shared_ptr&作为参数

但有多少情况下你不确定?所以这种情况很少见

Scott、Andrei和Herb在c++ and Beyond 2011的Ask Us Anything会议上讨论并回答了这个问题。从4:34开始观看shared_ptr的性能和正确性。

简单地说,没有理由按值传递,除非目标是共享对象的所有权(例如:共享对象的所有权)。不同的数据结构之间,或不同的线程之间)。

除非你可以像Scott Meyers在上面链接的演讲视频中解释的那样对它进行移动优化,但这与你可以使用的实际c++版本有关。

这个讨论的主要更新发生在GoingNative 2012会议的互动小组:问我们任何事情!值得一看,尤其是22:50开始。

Shared_ptr不够大,它的构造函数\析构函数也没有做足够的工作,因此拷贝有足够的开销来关心按引用传递和按复制传递的性能。

通过const引用传递,它更快。如果你需要存储它,比如在某个容器中,引用计数将通过复制操作自动神奇地增加。

以下是Herb Sutter的观点

Guideline: Don’t pass a smart pointer as a function parameter unless you want to use or manipulate the smart pointer itself, such as to share or transfer ownership. Guideline: Express that a function will store and share ownership of a heap object using a by-value shared_ptr parameter. Guideline: Use a non-const shared_ptr& parameter only to modify the shared_ptr. Use a const shared_ptr& as a parameter only if you’re not sure whether or not you’ll take a copy and share ownership; otherwise use widget* instead (or if not nullable, a widget&).