Reputation: 523
I have a very basic question about std::shared_ptr. If I have some
std::shared_ptr<A> p;
, where A is some class defined in my code, what is the preferred way to pass this std::shared_ptr as a function argument? Does it make a sense to define my functions that does something with the instance of class A like this:
void func(A &a);
and pass *p to these functions, and then convert 'a' back to std::shared_ptr with shared_from_this() if needed? Is there a reason to do so and what is the common practice? Or I should pass shared_ptr as the argument like this:
void func(std::shared_ptr<A> p); //thread safe
void func(const std::shared_ptr<A> & p); //not thread safe
In the most functions in my project I can use both alternatives, but my colleague said that the first alternative is better because the reference (A&) is always better than a pointer (shared_ptr or A*), because the reference semantics implies that the argument is not null.
Upvotes: 0
Views: 420
Reputation: 13713
If you already have a shared pointer, it does not make sense not to pass the shared_ptr
, yet create a new one by shared_from_this
. That's simply complicated and does not earn you anything.
The usual advice is passing objects by value if the function needs to make a copy anyway (e.g. for storing the object) and passing by const reference if the function only needs to "view" the object.
This also applies to shared pointers.
Hence, e.g.
// 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 ();
}
I cannot imagine a situation where passing a shared_ptr by reference would imply problems with thread safety that could be avoided by passing by value. Of course, you should avoid holding a reference to a shared pointer in a thread that does not hold a copy of the shared pointer anywhere. Yet as soon as the thread has a copy of the shared pointer, you can pass references to that shared pointer freely within this thread.
Upvotes: 1