Programmer
Programmer

Reputation: 8727

Passing a shared pointer to a function argument - what is the right way to assign it to a local variable

//header file
void SetLogger(const std::shared_ptr<A>& log);

//cpp file
void SetLogger(const std::shared_ptr<A>& log)
{
    std::shared_ptr<A>&  mLog;
    mLog = log;
}

What is the best way to pass a shared_ptr as a function argument such that the owner ship of the object referred to does not to change / no increment of reference count and that no body should be able to delete it accept the owner?

So how should create a local shared_ptr in the function stating the restriction above?

Caller:

SetLogger(A.get()); // A is actually a shared pointer

Header:

void SetLogger(const A& log);

CPP File:

void SetLogger(const A& log)
{
    auto mLog = std::make_shared<A>(log);
}

Upvotes: 3

Views: 9227

Answers (2)

lubgr
lubgr

Reputation: 38325

The rule of thumb for smart pointer function arguments is: if there is no notion of ownership, don't pass the smart pointer, pass the pointee

  1. as a reference, if it can't be null (preferable, see comments)
  2. as a pointer, if it can be null (don't forget to check, though)

In case 1, any call to delete on the argument will fail to compile, which might be desirable. Further const qualification of the argument is orthogonal. In your example:

void SetLogger(const A& log);

called like this

auto a = std::make_shared<A>(/* ... */);

SetLogger(*a);

So how should create a local shared_ptr in the function stating the restriction above?

If you need to copy the argument, there is indeed a notion of ownership. In that case, change your function signature to

void SetLogger(std::shared_ptr<A> log);

This will, however, increment the reference count, but if the object is managed by a std::shared_ptr, there is no sane solution to retain a copy without touching the reference count (for a good reason, this it what the class is about).

Upvotes: 11

Sebastian Schmitz
Sebastian Schmitz

Reputation: 515

If you don't want the called function to have ownership over your object, there is nothing wrong in passing a raw pointer as stated here. Make your logger a std::unique_ptr<A> and pass the pointer using the get() method. In modern C++ it is now clear to all users of the function that they don't own that pointer and are not supposed to delete it. The owner will do that.

Upvotes: 2

Related Questions