title: mechanism that make a string empty after std::move() it
body: <p>I have some confusion about how a <code>std::move()</code> really empty something.</p>
  
  <p>I write some code:</p>
  
  <pre><code>int main()
  {
      string str1("this is a string");
      std::cout&lt;&lt;std::boolalpha&lt;&lt;str1.empty()&lt;&lt;std::endl;
      string str2(std::move(str1));
      cout&lt;&lt;"str1: "&lt;&lt;str1.empty()&lt;&lt;endl;
      cout&lt;&lt;"str2: "&lt;&lt;str2.empty()&lt;&lt;endl;
  }
  </code></pre>
  
  <p>The output is:</p>
  
  <p><strong>false</strong></p>
  
  <p><strong>true</strong>  //this mean the original string is emptied</p>
  
  <p><strong>false</strong></p>
  
  <p>Why is the original string emptied every time?
  I have read some meterial about the move semantics,including the original proposal of it(<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm" rel="nofollow">this one</a>), which said:</p>
  
  <blockquote>
    <p>The difference between a copy and a move is that a copy leaves the source unchanged. A move on the other hand leaves the source in a state defined differently for each type. The state of the source may be unchanged, or it <strong>may be radically different</strong>. The only requirement is that the object remain in a self consistent state (all internal invariants are still intact). From a client code point of view, choosing move instead of copy means that you don't care what happens to the state of the source.</p>
  </blockquote>
  
  <p>So,according to this words, the original content of the <strong>str1</strong> above should be some kind of <strong>undefined</strong>. But why is that every time it have been <code>move()</code>, it is emptied?  (Actually I have test this behavior on both <code>std::string</code> and <code>std::vector</code> but the result is the same.)</p>
  
  <p>To learn more, I define my own string class to test, as bellow:</p>
  
  <pre><code>class mstring
  {
  private:
      char *arr;
      unsigned size;
  public:
      mstring():arr(nullptr),size(0){}
      mstring(char *init):size(50)
      {
          arr = new char[size]();
          strncpy(arr,init,size);
          while(arr[size-1] != '\0') //simply copy 
          {
              char *tmp = arr;
              arr = new char[size+=50]();
              strncpy(arr,tmp,50);
              delete tmp;
              strncpy(arr-50,init+(size-50),50);
          }
      }
  
      bool empty(){ return size==0;}
  
  }
  </code></pre>
  
  <p>Doing the same thing:</p>
  
  <pre><code>int main()
  {
      mstring str("a new string");
      std::cout&lt;&lt;std::boolalpha&lt;&lt;str.empty()&lt;&lt;std::endl;
      mstring anotherStr(std::move(str));
      std::cout&lt;&lt;"Original: "&lt;&lt;str.empty()&lt;&lt;std::endl;
      std::cout&lt;&lt;"Another: "&lt;&lt;anotherStr.empty()&lt;&lt;std::endl;
  }
  </code></pre>
  
  <p>The output is:</p>
  
  <p><strong>false</strong></p>
  
  <p><strong>Original: flase</strong>  //mean that the original string is still there</p>
  
  <p><strong>Another: false</strong></p>
  
  <p>Even I add a move constructor like this:</p>
  
  <pre><code>    mstring(mstring&amp;&amp; rvalRef)
      {
          *this = rvalRef;
      }
  </code></pre>
  
  <p>The result is still the same.
  My question is: why is the <code>std::string</code> get emptied but my self-defined isn't?</p>