Here you are in the gray area: enable_shared_from_this usually implemented using the shared_ptr constructors, which take responsibility for the raw pointer to the object obtained from enable_shared_from_this , set a weak_ptr contained within the object. Thus, later calls to shared_from_this() should return something. When you "reparent" sharedFoo , the original weak_ptr overwritten so that it contains the expired value when you finally call shared_from_this .
It is possible that this behavior is prohibited by the standard, but I think it is more likely that it is allowed, and that the semantics of ownership are slightly unproven in this admittedly niche corner business. The standard states that " shared_ptr constructors that create unique pointers can detect the existence of the enable_shared_from_this base and assign the newly created shared_ptr its __weak_this member __weak_this " ([Util.smartptr.enab] / 11). Despite the fact that the notes are not normative, I think that this indicates the intention of the standard.
You can avoid the problem altogether by creating a truly empty shared_ptr that has no ownership, but nonetheless points to sharedFoo :
std::shared_ptr<Foo> nonDeletingSharedFoo(std::shared_ptr<Foo>(), sharedFoo.get());
This uses the aliasing constructor:
template<class Y> shared_ptr(const shared_ptr<Y>& r, T* p) noexcept;
which creates shared_ptr , which has ownership of r , in this case the empty shared_ptr and points to p . The result is an empty (non-owning) shared_ptr that points to the same object as sharedFoo .
You are responsible for ensuring that such a pointer that does not have ownership is not dereferenced after the expiration of the referent. It would probably be better to clear the design so that you really share the property or use a raw pointer instead of breaking the "non-owning shared_ptr".
Casey source share