我有一个关于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 *)更好,因为引用语义意味着参数不为空。
答案 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意味着线程安全问题可以通过传递值来避免的情况。当然,您应该避免在不保存共享指针副本的线程中保持对共享指针的引用。然而,只要线程有共享指针的副本,就可以在此线程中自由地传递对该共享指针的引用。