Non-Polymorphic Shared Pointers: Unveiling the Secrets
The heated debate between Mr. Lidström and Mr. Tsirunyan raises a fundamental question: is it feasible to implement shared_ptr without mandating virtual destructors for polymorphic classes?
Mr. Lidström's assertion that shared_ptr
However, the C 11 standard and the Boost library demonstrate that such an implementation is indeed possible. This feat is accomplished through the concept of "type erasure":
template<class T> class shared_ptr { public: ... template<class Y> explicit shared_ptr(Y* p); ... };</p> <p>In the example provided, shared_ptr<Base><sp(new Derived);, the templated constructor with Y=Derived creates and initializes the shared_ptr object. Crucially, this constructor stores a pointer to a control block containing the reference counters and a deleter object tailored specifically for the Derived class.</p> <p>When the reference count drops to zero, the deleter object, armed with its knowledge of the Derived class's structure, is invoked to dispose of the allocated memory.</p> <p>The C 11 standard explicitly specifies this behavior in the requirements for the constructor:</p> <pre class="brush:php;toolbar:false">Requires: ... The expression delete p shall be well formed, shall have well defined behaviour and shall not throw exceptions. Effects: Constructs a shared_ptr object that owns the pointer p.
This ensures that the deleter is properly invoked and the memory is released safely, even if the pointer was cast from Derived to Base.
Similarly, the standard outlines the destructor's behavior:
Effects: ... Otherwise, if *this owns a pointer p, and delete p is called.
By utilizing templated constructors and type erasure, shared_ptr can avoid the need for virtual destructors in polymorphic classes, enabling efficient memory management for a wider range of scenarios.
The above is the detailed content of Can `shared_ptr` Work Without Virtual Destructors in Polymorphic Classes?. For more information, please follow other related articles on the PHP Chinese website!