There are two distinct reference counts involved for a shared_ptr
shared object:
- The number of references to the object, i.e.
shared_ptr
instances. - The number of references to the control block, i.e.
shared_ptr
andweak_ptr
instances.
A weak_ptr
contributes only to the latter count. When all shared_ptr
instances have been destroyed, the object deleter is called, which usually is the default one that destroys the object. The control block still exists if there are weak pointers. When also all weak pointers have been destroyed, the control block is destroyed.
So (ignoring possible optimization of caching object pointer directly in each shared_ptr
instance), in your case you have x
pointing (hidden for you) to the control block, which has a pointer to the A
instance. And you have the b
member of that instance pointing to a second control block, which has a pointer to a B
instance. Finally that instance has a pointer to the control block that x
points to, which is circular yes, but not a circularity of ownership.