Should I pass shared_ptr by reference?

What are the best methods to pass shared_ptr?

I am currently passing arguments to the shared_ptr function as follows:

void function1( shared_ptr<TYPE>& value ); 
+76
c ++ shared-ptr
Dec 05 '11 at 12:40
source share
3 answers

In controlled circumstances, you can pass a shared pointer through a permalink. Make sure that no one is deleting the object at the same time, although it should not be too difficult if you are careful about who you link to.

In general, you should pass a generic pointer as a direct copy. This gives it the intended semantics: each area containing a copy of the common index keeps the object alive by virtue of its "share" in the property.

The only reason why it is not always necessary to pass by value is that the common pointer is copied at a certain price by updating the number of references to atoms; however, this may not be a serious problem.




Additional retreat:

Since the main question has been answered, it may be instructive to consider several ways to use a never- shared index. Here is a little thought experiment. Define the generic pointer type SF = std::shared_ptr<Foo> . To consider links, rather than passing arguments to functions, let's look at the type RSF = std::reference_wrapper<T> . That is, if we have a common pointer SF p(std::make_shared<Foo>()); , then we can create a reference shell with semantics values โ€‹โ€‹through RSF w = std::ref(p); . So much to customize.

Now everyone knows that pointer containers are a minefield. Thus, std::vector<Foo*> will become a maintenance nightmare, and any number of errors will result from improper lifecycle management. Worse conceptually, it is never clear who owns the objects whose pointers are stored in the container. Pointers can be a combination of pointers to dynamic objects, automatic objects, and garbage. No one can say. Therefore, the standard solution is to use std::vector<SF> . This is the correct way to use a shared pointer. On the other hand, what you should never use is std::vector<RSF> - it is an uncontrollable monster that is actually very similar to the original vector of bare pointers! For example, it is unclear whether the object to which you are holding a link is alive. Taking a reference to a common index defeated the entire target.

For the second example, suppose we have a common pointer SF p , as before. Now we have an int foo(SF) function that we want to run at the same time. The regular std::thread(foo, p) works just fine, as the thread constructor creates a copy of its arguments. However, if we said std::thread(foo, std::ref(p)) , we would have all kinds of problems: a common pointer in the call area may expire and destroy the object, and you will remain with a broken link and an invalid pointer!

I hope these two admittedly pretty far-fetched examples shed some light when you really want your generic pointers to be passed in a copy. In a well-designed program, it should always be clear who is responsible for what resources, and if used correctly, a common index is an excellent tool for working.

+79
Dec 05 2018-11-12T00:
source share

It depends on what you want. Should this group own the property? Then he needs his own copy of shared_ptr . Therefore pass it by value.

If the function just needs to access the object owned by the caller, follow the link (const) to avoid the overhead of copying shared_ptr .

Best practice in C ++ should always have well-defined property semantics for your objects. There is no universal โ€œalways do thisโ€ to replace real thought.

If you always pass generic pointers by value, this becomes expensive (because they are much more expensive than the original pointer). If you never do this, then it makes no sense to use a generic pointer in the first place.

Copy the generic pointer when a new function or object needs to transfer ownership of pointee.

+21
Dec 05 2018-11-12T00:
source share

Pass it by const link if you follow the link. This makes it clear that you are following the link for performance reasons. Also, use make_shared when you can, as it retains indirection, therefore it provides a level boost.

+8
Dec 05 '11 at 12:53 on
source share



All Articles