[c++] 我们应该通过引用还是通过值来传递shared_ptr?


Answers

这是Herb Sutter的要求

指南:除非您想使用或操纵智能指针本身,例如共享或传输所有权,否则不要将智能指针作为函数参数传递。

指南:表示函数将使用by-value shared_ptr参数存储和共享堆对象的所有权。

指南:只使用非const的shared_ptr&参数来修改shared_ptr。 只有在您不确定您是否要复制并共享所有权时才使用const shared_ptr&作为参数; 否则使用小部件*代替(或者如果不是可空的,一个小部件&)。

Question

当一个函数需要一个shared_ptr (来自boost或C ++ 11 STL)时,你是否传递它

  • 通过const引用: void foo(const shared_ptr<T>& p)

  • 或通过值: void foo(shared_ptr<T> p)

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

你能否给出你选择的理由,或者如果是这种情况,为什么你认为这没有关系。




自从C ++ 11以来,你应该把它比const更频繁地使用它这比你想像的要多得多。

如果你正在使用std :: shared_ptr(而不是基础类型T),那么你是这么做的,因为你想对它做些什么。

如果你想将它复制到某个地方,通过拷贝将它拷贝,std :: move在内部更合理,而不是通过const&来获取,然后再拷贝它。 这是因为你在调用你的函数时允许调用者选择std ::移动shared_ptr,从而为你自己节省一组增量和减量操作。 或不。 也就是说,函数的调用者可以在调用函数后决定他是否需要std :: shared_ptr,并根据是否移动来决定。 如果你通过const&来传递,那么这是不可实现的,因此它最好是按值取值。

当然,如果调用者都需要更长的shared_ptr(因此不能std :: move它),并且你不想在函数中创建一个简单的副本(比如说你想要一个弱指针,或者你只是有时想复制它,取决于某些条件),那么const&可能仍然是可取的。

例如,你应该这样做

void enqueue(std::shared<T> t) m_internal_queue.enqueue(std::move(t));

过度

void enqueue(std::shared<T> const& t) m_internal_queue.enqueue(t);

因为在这种情况下,你总是在内部创建一个副本




shared_ptr不够大,它的构造函数\析构函数也没有做足够的工作来从副本获得足够的开销,以关心引用传递与传递复制性能。




通过const引用传递,速度更快。 如果你需要存储它,比如在一些容器中,参考文献。 计数将通过复制操作自动增加。






Links