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

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

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

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


当前回答

就我个人而言,我会使用const引用。没有必要为了函数调用而增加引用计数。

其他回答

就我个人而言,我会使用const引用。没有必要为了函数调用而增加引用计数。

从c++ 11开始,你应该比你想象的更经常地通过值而不是参数来使用它。

如果您正在使用std::shared_ptr(而不是底层类型T),那么您这样做是因为您想对它做一些事情。

If you would like to copy it somewhere, it makes more sense to take it by copy, and std::move it internally, rather than taking it by const& and then later copying it. This is because you allow the caller the option to in turn std::move the shared_ptr when calling your function, thus saving yourself a set of increment and decrement operations. Or not. That is, the caller of the function can decide whether or not he needs the std::shared_ptr around after calling the function, and depending on whether or not move or not. This is not achievable if you pass by const&, and thus it is then preferably to take it by value.

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

例如,你应该这样做

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

over

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

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

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

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

以下是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&).