Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Yes, it is possible to implement shared_ptr that way. Boost does and the C++11 standard also requires this behaviour. As an added flexibility shared_ptr manages more than just a reference counter. A so-called deleter is usually put into the same memory block that also contains the reference counters. But the fun part is that the type of this deleter is not part of the shared_ptr type. This is called "type erasure" and is basically the same technique used for implementing the "polymorphic functions" boost::function or std::function for hiding the actual functor's type. To make your example work, we need a templated constructor:</p> <pre><code>template&lt;class T&gt; class shared_ptr { public: ... template&lt;class Y&gt; explicit shared_ptr(Y* p); ... }; </code></pre> <p>So, if you use this with your classes Base and Derived ...</p> <pre><code>class Base {}; class Derived : public Base {}; int main() { shared_ptr&lt;Base&gt; sp (new Derived); } </code></pre> <p>... the templated constructor with Y=Derived is used to construct the shared_ptr object. The constructor has thus the chance to create the appropriate deleter object and reference counters and stores a pointer to this control block as a data member. If the reference counter reaches zero, the previously created and Derived-aware deleter will be used to dispose of the object.</p> <p>The C++11 standard has the following to say about this constructor (20.7.2.2.1):</p> <blockquote> <p><em>Requires:</em> <code>p</code> must be convertible to <code>T*</code>. <code>Y</code> shall be a complete type. <strong>The expression <code>delete p</code> shall be well formed, shall have well defined behaviour and shall not throw exceptions.</strong></p> <p><em>Effects:</em> Constructs a <code>shared_ptr</code> object <strong>that <em>owns</em> the pointer <code>p</code>.</strong></p> <p>…</p> </blockquote> <p>And for the destructor (20.7.2.2.2):</p> <blockquote> <p><em>Effects:</em> If <code>*this</code> is <em>empty</em> or shares ownership with another <code>shared_ptr</code> instance (<code>use_count() &gt; 1</code>), there are no side effects. Otherwise, if <code>*this</code> owns an object <code>p</code> and a deleter <code>d</code>, <code>d(p)</code> is called. <strong>Otherwise, if <code>*this</code> owns a pointer <code>p</code>, and <code>delete p</code> is called.</strong></p> </blockquote> <p>(emphasis using bold font is mine).</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload