Must enable_shared_from_this be the first base class?

Filipp :

My class inherits from multiple bases, one of which is std::enable_shared_from_this. Must it be the first base?

Suppose the following example code:

struct A { ~A(); };
struct B { ~B(); };
struct C : A, B, std::enable_shared_from_this<C> {};

std::make_shared<C>(); 

When ~A() and ~B() run, can I be sure that the storage where C lived is still present?

curiousguy :

When ~A() and ~B() run, can I be sure that the storage where C lived is still present?

Of course! It would be hard to use a base class that tries to free its own memory (the memory where it resides). I'm not sure it's even formally legal.

Implementations don't do that: when a shared_ptr<T> is destructed or reset, the reference count (RC) for the shared ownership of T is decremented (atomically); if it reached 0 in the decrement, then destruction/deletion of T is started.

Then the weak-owners-or-T-exists count is decremented (atomically), as T no longer exists: we need to know if we are the last entity standing interested in the control block; if the decrement gave a non zero result, it means some weak_ptr exist that share (could be 1 share, or 100%) ownership of control block, and they are now responsible for the deallocation.

Either way, atomic decrement will at some point end up with a zero value, for the last co-owner.

Here there are no threads, no non-determinism, and obviously the last weak_ptr<T> was destroyed during destruction of C. (The unwritten assumption in your question being that no other weak_ptr<T> was kept.)

Destruction always happen in that exact order. The control block is used for destruction, as no shared_ptr<T> knows (in general) which (potentially non virtual) destructor of (potentially different) most derived class to call. (The control block also knows not to deallocate memory on shared count reaching zero for make_shared.)

The only practical variation between implementations seems to be about the fine details of memory fences and avoiding some atomic operations in common cases.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=368837&siteId=1