The point of shared_ptr
is to express shared ownership.
Anything that does not share in the ownership of an object -- that doesn't have the right to make an object lifetime last longer, and the object lifetime is the union of the shared owners request for object lifetime -- should not use a shared_ptr
.
Here, you have a shared_ptr
and you are going to return it. At that point, you are violating the assumptions of shared_ptr
; anyone who kept a shared_ptr
copy expects that its content can last as long as it requests.
Meanwhile, the calling code thinks it owns the MyObject*
raw pointer you passed it.
This is an example of misuse of shared_ptr
.
Saying "we have memory management issues, use shared_ptr
" doesn't fix memory management issues. Proper use of shared_ptr
requires care and design, and the design must be that when the end of the lifetime of the object in question is shared by 2 or more pieces of data and/or code.
The internal code, if it does not own the pointer, should use either something like an observer_ptr<T>
or a raw T*
(the first to make it clear it doesn't own the object).
Ownership should be explicit, and in a unique_ptr
. It can then call .release()
to pass ownership to a raw pointer if required; in practice, I would change your signature to take a unique_ptr&
, or have it return a unique_ptr
.
The caller would then call .release()
when they want to use some other object lifetime management system, or that object lifetime management system should consume unique_ptr
s (thus being extremely clear about taking ownership of things).
Use a non-hack solution.
Such as a std::shared_ptr<std::unique_ptr<T>>
. In this case, you have shared ownership of a unique ownership.
The unique_ptr
can have its ownership taken from it (via .release()
). When it does so, all of the shared_ptr
s that still exist will have their unique_ptr
also be cleared.
This places the shared unique ownership front and center, instead of hacking a non-deleter into a shared_ptr and having dangling shared_ptrs that think they have ownership over data but do not.