Reputation: 35982
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:
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
return by reference, so that I can avoid +/- of the reference count of shared_ptr
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
Thank you
Upvotes: 1
Views: 690
Reputation: 418
It will depend on what the function does:
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