cpp/memory/shared ptr

is a smart pointer that retains shared ownership of an object through a pointer. Several objects may own the same object. The object is destroyed and its memory deallocated when either of the following happens:
 * the last remaining owning the object is destroyed;
 * the last remaining owning the object is assigned another pointer via operator= or reset.

The object is destroyed using delete-expression or a custom deleter that is supplied to during construction.

A can share ownership of an object while storing a pointer to another object. This feature can be used to point to member objects while owning the object they belong to. The stored pointer is the one accessed by get, the dereference and the comparison operators. The managed pointer is the one passed to the deleter when use count reaches zero.

A may also own no objects, in which case it is called empty (an empty  may have a non-null stored pointer if the aliasing constructor was used to create it).

All specializations of meet the requirements of, , and  and are contextually convertible to.

All member functions (including copy constructor and copy assignment) can be called by multiple threads on different instances of without additional synchronization even if these instances are copies and share ownership of the same object. If multiple threads of execution access the same instance of without synchronization and any of those accesses uses a non-const member function of  then a data race will occur; the  can be used to prevent the data race.

Implementation notes
In a typical implementation, holds only two pointers:
 * the stored pointer (one returned by get);
 * a pointer to control block.

The control block is a dynamically-allocated object that holds:
 * either a pointer to the managed object or the managed object itself;
 * the deleter (type-erased);
 * the allocator (type-erased);
 * the number of s that own the managed object;
 * the number of s that refer to the managed object.

When is created by calling std or std, the memory for both the control block and the managed object is created with a single allocation. The managed object is constructed in-place in a data member of the control block. When is created via one of the  constructors, the managed object and the control block must be allocated separately. In this case, the control block stores a pointer to the managed object.

The pointer held by the directly is the one returned by get, while the pointer/object held by the control block is the one that will be deleted when the number of shared owners reaches zero. These pointers are not necessarily equal.

The destructor of decrements the number of shared owners of the control block. If that counter reaches zero, the control block calls the destructor of the managed object. The control block does not deallocate itself until the std counter reaches zero as well.

In existing implementations, the number of weak pointers is incremented if there is a shared pointer to the same control block.

To satisfy thread safety requirements, the reference counters are typically incremented using an equivalent of std with std (decrementing requires stronger ordering to safely destroy the control block).