title: placement new with derived class
body: <p>C++ gurus. Need your help with this little head scratcher:</p>
  
  <pre><code>#include &lt;iostream&gt;
  struct B{
      virtual ~B() = default;
      virtual void talk() { std::cout &lt;&lt; "Be-e-e\n"; }
  };
  
  struct D:B{
      void talk() override { std::cout &lt;&lt; "Duh\n"; }
      ~D() { std::cout &lt;&lt; "~D()\n"; }
  };
  
  int main(){
      B b{};      // vptr points to B
      new (&amp;b) D; // vptr now points to D
      b.talk();   // "Be-e-e" (why? shouldn't the vptr be used?)
      b = D{};    // "~D()" (why? shouldn't the copying be elided?)
      b.talk();   // "Be-e-e"
  
      B*b1{new D};
      b1-&gt;talk(); // "Duh"
      delete b1;  // "~D()"
  
      return 0;
  }
  </code></pre>
  
  <p>The code is pretty straightforward: have a base object on stack, placement-new a derived one into it (yes, eeew, but bear with me) and calling a virtual method, expecting a derived's output to be printed.</p>
  
  <h2>Actual output</h2>
  
  <p>The code above produces the following output:</p>
  
  <pre>
  Be-e-e
  ~D()
  Be-e-e
  Duh
  ~D()
  </pre>
  
  <p>That behavior is universally observed on MSVC, gcc, clang, and a few online compilers I tried it on (which is an extremely strong indication that it is I who am wrong).</p>
  
  <h2>Part 1</h2>
  
  <p>The placement-new re-news a derived-type object into the base-type memory. And that updates the vptr to point to the derived-type's vtable (directly observed in the debugger).</p>
  
  <p><strong>Main question</strong>: is that the expected behavior? (I want to say "yes" so if it is not - please explain to me)</p>
  
  <p>I want to believe that performing a placement-new (provided there's enough memory for the derived-type object) should in-place initialize a brand new object of the derived-type.</p>
  
  <hr>
  
  <p>If my understanding is correct, the first <code>b.talk()</code> should output <code>"Duh"</code> as the object now is of derived-type. Why is it still printing <code>"Be-e-e"</code>?</p>
  
  <p>Assigning a derived-type object into the base-type object (in addition to causing object splicing) does not copy the vptr, so that second <code>"Be-e-e"</code> output is expected, provided the object is still of the base-type when we get to that line of code.</p>
  
  <h2>Part 2</h2>
  
  <p>Why is there a <code>~D()</code> call in the <code>b = D{};</code> assignment? Isn't it a temporary that should be copy-elided with no need for a destructor call on that temporary?</p>
  
  <h2>Part 3</h2>
  
  <p>The last block of code that uses pointers works "as expected" and is just here for sanity check</p>