将此std :: shared_ptr作为函数参数传递的首选方法是什么?

时间:2017-05-25 09:58:48

标签: c++11

我有一个关于std :: shared_ptr的非常基本的问题。如果我有一些

std::shared_ptr<A> p;

,其中A是我的代码中定义的某个类,将此std :: shared_ptr作为函数参数传递的首选方法是什么?将这样的函数定义为使用类A的实例执行某些操作是否有意义:

void func(A &a);

并将* p传递给这些函数,然后根据需要将'a'转换回带有shared_from_this()的std :: shared_ptr?是否有理由这样做,通常的做法是什么?或者我应该将shared_ptr作为参数传递:

void func(std::shared_ptr<A> p); //thread safe
void func(const std::shared_ptr<A> & p); //not thread safe

在我的项目中的大多数函数中,我可以使用两种替代方法,但我的同事说第一种方法更好,因为引用(A&amp;)总是比指针(shared_ptr或A *)更好,因为引用语义意味着参数不为空。

1 个答案:

答案 0 :(得分:1)

如果您已经有一个共享指针,那么不通过shared_ptr,而是通过shared_from_this创建一个新指针是没有意义的。这简直很复杂,也没有给你带来任何好处。

通常的建议是,如果函数需要复制(例如存储对象)并通过const引用传递,如果函数只需要“查看”对象,则按值传递对象。

这也适用于共享指针。

因此,例如

// Here func in the end needs a copy of the shared_ptr, so pass by value
// the caller can decide whether he wants to move or a copy it in
struct Example {
  shared_ptr<A> m_a;
  void func (shared_ptr<A> a) {
     m_a = move (a);
  }
};

// Here func needs only a reference, so only pass a reference
void func (shared_ptr<A> const & a) {
   a->callme ();
}

// If func needs to see only an object of type A, i.e. does not
// need a pointer, it makes
// more sense to pass an A & or A const &
void func (A const & a) {
   a.callme ();
}

我无法想象通过引用传递shared_ptr意味着线程安全问题可以通过传递值来避免的情况。当然,您应该避免在不保存共享指针副本的线程中保持对共享指针的引用。然而,只要线程有共享指针的副本,就可以在此线程中自由地传递对该共享指针的引用。