Quoted from C++ Primer $12.1.6:
A
weak_ptr(Table 12.5) is a smart pointer that does not control the lifetime of the object to which it points. Instead, a weak_ptr points to an object that is managed by ashared_ptr. Binding a weak_ptr to a shared_ptr does not change the reference count of thatshared_ptr. Once the lastshared_ptrpointing to the object goes away, the object itself will be deleted. That object will be deleted even if there areweak_ptrspointing to it—hence the nameweak_ptr, which captures the idea that aweak_ptrshares its object “weakly.”
However,I've read an article says:
using make_shared is more efficient. The shared_ptr implementation has to maintain housekeeping information in a control block shared by all shared_ptrs and weak_ptrs referring to a given object. In particular, that housekeeping information has to include not just one but two reference counts:
A “strong reference” count to track the number of shared_ptrs currently keeping the object alive. The shared object is destroyed (and possibly deallocated) when the last strong reference goes away.
A “weak reference” count to track the number of weak_ptrs currently observing the object. The shared housekeeping control block is destroyed and deallocated (and the shared object is deallocated if it was not already) when the last weak reference goes away.
As far as I know,the shared_ptr created by make_shared is in the same control block with those ref countings.So the object will not be released until the last weak_ptr expires.
Question:
- Is the Primer wrong? Because
weak_ptrwill actually affects the lifetime of that object. - Why does the
shared_ptrneed to track its weak refs?The weak_ptr can tell if the object exists by checking the strong refs in control blocks,so I think the control block does not need to track the weak refs. Just for curiosity,what does the control block created by
shared_ptrlook like?Is it something like:template<typename T> class control_block { T object; size_t strong_refs; size_t weak_refs; void incre(); void decre(); //other member functions... }; //And in shared_ptr: template<typename T> class shared_ptr { control_block<T> block;//Is it like this?So that the object and refs are in the same block? //member functions... };
pointed to objectthat is deleted when the last shared_ptr is removed and thecontrol block objectthat contains the reference count that is deleted when the last managed pointer to it is deleted (including shared and weak ptrs) - PeterTdelete ptrdestroys the pointed to object by calling its destructor if it has any, which end the lifetime of the object and then calls operator delete(), which can be specific for the object type, that (by default) deallocates the heap memory that was allocated for the object. - Maarten Hilferink