q0987
q0987

Reputation: 35982

what is a good return type ` boost::shared_ptr<StructA>`?

The function needs to return a shared_ptr pointing to StructA.

struct StructA
{
    // complicated struct that also holds other sub-structure
    ....
};

const boost::shared_ptr<const StructA&>& GetStructA(...)
{...} #0.5

const boost::shared_ptr<const StructA>& GetStructA(...)
{...} #0

const boost::shared_ptr<StructA>& GetStructA(...)
{...} #1

const boost::shared_ptr<StructA> GetStructA(...)
{...} #2

boost::shared_ptr<const StructA> 
{...} #3

boost::shared_ptr<StructA> GetStructA(...)
{...} #4

boost::shared_ptr<StructA>& GetStructA(...)
{...} #5

boost::shared_ptr<StructA&> GetStructA(...)
{...} #6

There are so many choices and I am sure one of them is best(pls point out if there is anyone left).

Personally, I prefer to using #0

const boost::shared_ptr<const StructA&>& GetStructA(...)
{...} #0

The legacy system uses #2

const boost::shared_ptr<StructA>  GetStructA(...)
{...} #2

The reason why I prefer to choosing #0 is as follows:

  1. return const shared_ptr, so that the caller of this function should NOT change the returned shared_ptr which may point to internal data structure

  2. return by reference, so that I can avoid +/- of the reference count of shared_ptr

  3. the shared_ptr holds const StructA&, so that the caller cannot change the content of the const shared_ptr. If I were right, even if the shared_ptr is const, it cannot prevent the caller from changing the pointed data unless the data is const.

Please

  1. correct my understanding if I made any mistake
  2. provide a best return signature for this function.

Thank you

Upvotes: 1

Views: 690

Answers (1)

ierceg
ierceg

Reputation: 418

It will depend on what the function does:

  • Is it creating a new object of StructA? If yes, then you must return a copy of shared_ptr.
  • Is it just providing access to a StructA object that you know will not expire under the returned referece? Then you could return const& on it (but don't - see below)

As you yourself suspect, const& on shared_ptr won't prevent non-const access to the object it points to - it just means that shared_ptr object itself is constant and cannot be reset or pointed to some other object. The semantics of shared_ptr, in this case, are the same as with semantics of the plain pointers.

I used to use const& idiom a lot when returning access pointers. But at the end it can lead to very subtle bugs especially in multithreaded code (I'm careful but I still got bitten). So peachykeen's comment above is spot on and I follow that idiom for all new code. Not only for returns mind you but also when a function argument is a shared_ptr. At the end you really want to know that whenever you have an object pointed by a shared_ptr - you really have it and not just a reference of a shared_ptr of a long dead object.

Upvotes: 2

Related Questions