What's the best practice when passing a shared pointer to a non-owner function?

I often run with shared pointers in a situation where I want to pass them to functions that don't own (should) own an object. Since I know the object is valid at the time of the function call, I have four options for passing a pointer:

  • by value
  • link
  • weak pointer
  • raw pointer

At first I started using weak pointers a lot (because I already had them), but the overhead of locking them annoys all the time and achieves performance. Now I am thinking about passing original pointers or shared pointers by reference. Is there a best practice?

+3


source to share


3 answers


I would suggest passing them on const std::shared_ptr<T>&

. This has two advantages:

  • No link counting overhead (default does not increase link count)
  • The function can take a copy of the shared pointer for free

I use this a lot in situations where they may (or may not) be streaming. For example:



struct Foo { void bar() {} };

class BaseImpl
{
public:
   void CallBar(const std::shared_ptr<Foo>& f);
   {
      do_call_bar(f);
   }

private:
   virtual void do_call_bar(const std::shared_ptr<Foo>& f) = 0;
};

class DerivedDirectCall : public BaseImpl
{
   virtual void do_call_bar(const std::shared_ptr<Foo>& f) override
   {
      f->bar();
   }
};

class DerivedAsyncCall : public BaseImpl
{
   virtual void do_call_bar(const std::shared_ptr<Foo>& f) override
   {
      // assume invoke passes this off
      // to be done asynchronously
      invoke([f] () { f->bar(); });
   }
};

      

Depending on whether the implementation is DerivedDirectCall

or DerivedAsyncCall

, the shared pointer will only be copied if necessary.

Also, the comment above is linked to this article on smart pointers . I want to be clear that my answer is mainly about passing the smart pointer itself. If you know the lifespan won't necessarily be extended, it's better to pass a pointer to an object by reference (or a raw pointer, but only need to allow parameters nullptr

).

+6


source


I often run with shared pointers in a situation where I want to pass them to functions that don't own (should) own an object.

Your wording sounds like your function really cares about what the object points to, not the pointer. So you have to pass the object (by reference):



void my_func(int &x);

int main()
{
    shared_ptr<int> demo_ptr = make_shared<int>(5);
    my_func(*demo_ptr);
}

      

+4


source


The lifespan is guaranteed by the stack. If you were to pass weak_ptr

, then the function would just have to receive shared_ptr

.

You want to either pass a raw pointer by value or an actual object by reference.

The choice between these two parameters depends on the semantics of the called function. If nullptr

is a valid argument for your function, then pass in a raw pointer. Otherwise, pass the object by reference.

+3


source







All Articles