title: Downcasting shared pointer to derived class with additional functionality - is this safe?
body: <p>Consider the following outline:</p>
  
  <pre><code>class Base { /* ... */ };
  
  class Derived : public Base
  {
  public:
      void AdditionalFunctionality(int i){ /* ... */ }
  };
  
  typedef std::shared_ptr&lt;Base&gt; pBase;
  typedef std::shared_ptr&lt;Derived&gt; pDerived;
  
  int main(void)
  {
      std::vector&lt;pBase&gt; v;
      v.push_back(pBase(new Derived()));
  
      pDerived p1(  std::dynamic_pointer_cast&lt;Derived&gt;(v[0])  ); /* Copy */
      pDerived p2 = std::dynamic_pointer_cast&lt;Derived&gt;(v[0]);    /* Assignment */
  
      p1-&gt;AdditionalFunctionality(1);
      p2-&gt;AdditionalFunctionality(2);
  
      /* A */
  
      return 0;
  }
  </code></pre>
  
  <p>Here I'm extending the base class with a derived class that adds functionality (the <code>AdditionalFunctionality</code> method).</p>
  
  <p>First question, is this OK?  I've read a lot of questions that say this is not okay and you should declare the additional functionality in the base class (often suggested as making them pure virtual methods in the base class).  However, I don't want to do this.  I want to <strong>extend</strong> the functionality of the base class, not just implement it differently.  Is there a better solution to accomplish this goal?</p>
  
  <p>Okay, so in this code I am also using an STL container to store these pointers which allows me to store pointers to both objects of type Base as well as objects of type Derived without slicing the objects.</p>
  
  <p>Second question, this makes sense, right?  I am, in fact, avoiding slicing by using pointers to base class objects rather than the base class objects themselves?</p>
  
  <p>If I "know" that a certain pointer is to a Derived object, I then use <code>std::dynamic_pointer_cast</code> to cast the smart pointer.</p>
  
  <p>Third question, this compiles without warning and works, but is it safe? Valid?  Will it break the reference counting aspect of shared pointers and fail to <code>delete</code> my objects  or <code>delete</code> them before I expect?</p>
  
  <p>Lastly, I can do this cast using either the copy constructor or via assignment as shown for p1 and p2.  Is there a preferred / correct way of doing this?</p>
  
  <p>Similar questions:</p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/1358143/downcasting-shared-ptrbase-to-shared-ptrderived">Downcasting shared_ptr&lt;Base&gt; to shared_ptr&lt;Derived&gt;?</a> : This is very close, however the dervied class does not add additional functionality like mine does, so I'm not sure it's completely the same.  Also, it uses <code>boost::shared_ptr</code> where I'm using <code>std::shared_ptr</code> (although I understand boost donated shared_ptr to the std library, so they're likely the same).</li>
  </ul>
  
  <p>Thank you for your help.</p>
  
  <hr>
  
  <p><strong>Edit:</strong></p>
  
  <p>One reason I ask is that I realize that the following could be done (incorrectly):</p>
  
  <pre><code>    /* Intentional Error */
      v.push_back(pBase(new Base()));
      pDerived p3( std::dynamic_pointer_cast&lt;Derived&gt;(v[1]) );
      p3-&gt;AdditionalFunctionality(3); /* Note 1 */
  </code></pre>
  
  <p>Where I attempt to downcast a pointer to a Base object to a pointer of a Derived object and then call a method that is only implemented in the Derived class.  In other words, the object pointed to doesn't define (or isn't even "aware of" the method).</p>
  
  <p>This is not caught by the compiler, but <em>may</em> cause a segfault depending on how <code>AdditionalFunctionality</code> is defined.</p>