4

This is strictly theoretical question. When project is based on smart pointers, so practically all classes use them to wrap their pointer members, is it a bad practise to pass ordinary pointers to member/not member functions? I mean, is it correct to have member functions like:

void Function(SomeClass* pSomeClass);

Or should it always be:

void Function(std::shared_ptr<SomeClass> pSomeClass);

I also wander if there are any important consequences (except standard const features) of passing const reference:

void Function(const std::shared_ptr<SomeClass>& pSomeClass)

What about situation when class is using std::unique_ptr to protect its members, and for example, pointer to its member is used in class private member function? Should it be wrapped too? Or should it be considered as design mistake?

7
  • Is the function doing anything with the shared pointer? Or is it just dereferencing it to use the stored object? Commented Dec 17, 2015 at 7:43
  • 3
    First of all, you should most of the time look at the new smart pointers in terms of ownership and not as a kind of self-deleting pointer. Then if you use smart pointers you need to use them everywhere for that pointer, just creating a shared_ptr for passing to a function makes no sense. Lastly, the smart pointers are supposed to be passed (or returned) by value, otherwise their semantics doesn't really work. Commented Dec 17, 2015 at 7:43
  • @Benjamin Lindley; most of times, it is just dereferencing it to use the stored object. Commented Dec 17, 2015 at 7:44
  • Then there is no reason for it to take a shared pointer. That just arbitrarily restricts the usefulness of the function. Commented Dec 17, 2015 at 7:45
  • 1
    Unless the function needs to know it's a smart pointer to affect its value then you should pass a raw pointer. So unless the function changes the smart pointer itself, it should accept a raw pointer or a reference. See this answer for more info: stackoverflow.com/a/32873826/3807729 Commented Dec 17, 2015 at 7:50

2 Answers 2

9

If the function only needs the pointed-to object and it must always be a valid object, not null, pass the object by reference (const or non-const, depending on the usual rules).

If the function only needs the pointed-to object, or optionally null, pass by raw pointer (to const or non-const, as per the usual rules).

If the function needs to share ownership of the pointed-to object, pass the shared_ptr by value.

If the function needs to modify the shared_ptr handle to the object (e.g. reset), pass the shared_ptr by non-const reference.

If the function needs to access information on the shared_ptr handle (such as use_count), but should not modify the shared_ptr, pass the shared_ptr by const reference.

Sign up to request clarification or add additional context in comments.

Comments

5

I think Herb Sutter has some good answers for that. There is a GotW about smart pointer usage, and a more recent presentation where he covers this. The new C++ Core Guidelines have a full section about smart pointer usage.

In a nutshell it all comes down "Take smart pointers as parameters only to explicitly express lifetime semantics". If you pass a smart pointer, this should imply that you talk/participate in ownership, either shared or unique. For non-owning parameters, raw pointers or (const) references are the current recommendation.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.