title: A canonical way to implement move semantics in a class
body: <p>I am looking for a good example of how to implement a derived and a base class with move semantics.  The more I have thought about it, the more it seems that the default move constructor and assignment move operator will normally do the job because most standard (STL) types and smart pointers are default moveable. </p>
  
  <p>Anyway, in the case we have a class hierarchy, which requires an explicit move implementation, how should I do it - at least as a first cut? </p>
  
  <p>In this example, I am using a raw pointer which I would normally wrap in a std::unique_ptr but I needed an example of something to move which is not default moveable.</p>
  
  <p>Any help would be much appreciated. :)</p>
  
  <p>Currently, I have made the following attempt:</p>
  
  <pre><code>struct BlobA
  {
      char data[0xaa];
  };
  
  struct BlobB
  {
      char data[0xbb];
  };
  
  //----------------------------------------
  
  class Base
  {
  public:
  
      //Default construct the Base class
      //C++11 allows the data members to initialised, where declared. Otherwise you would do it here.
      Base()
      {
  
      }
  
      //Define the destructor as virtual to ensure that the derived destructor gets called. (In case it is necessary. It's not in this example but still good practice.)
      virtual ~Base()
      {
          delete m_moveableDataInBase; //this is a contrived example to show non-default moveable data, in practice RAII should be used rather than deletes like this
      }
  
      //Copy constructor, needs to accept a const ref to another Base class with which it copies the data members
      Base(const Base&amp; other) :
      m_moveableDataInBase(new BlobA(*other.m_moveableDataInBase)), // copy the other's moveable data
      m_pNonMoveableDataInBase(other.m_pNonMoveableDataInBase)        // copy the other's non-moveable data
      {
  
      }
  
      //Assignment operator uses the canonical copy then swap idiom. It returns a reference to allow chaining: a = b = c
      //This is thus implemented in terms of the copy constructor.
      Base&amp; operator=(const Base&amp; rhs)
      {
          Base temp(rhs);
          Swap(temp);
          return *this;
      }
  
      //The move construtor is declared as throwing no exceptions so that it will be called by STL algorithms
      //It accepts an rvalue and moves the Base part.
      Base(Base&amp;&amp; other) noexcept :
      m_moveableDataInBase(nullptr) // don't bother allocating our own resources to moveable data because we are about to move (steal) the other's resource
      {
          Swap(other);
      }
  
      //The move assignment operator is declared as throwing no exceptions so that it will be called by STL algorithms
      //It accepts an rvalue and moves (steals) the data resources from the rhs using swap and copies the non moveable data from the rhs
      Base&amp; operator=(Base&amp;&amp; rhs) noexcept
      {
          //move (steal) the moveable contents from rhs
          std::swap(m_moveableDataInBase, rhs.m_moveableDataInBase);
  
          //copy the non-moveable contents from rhs
          m_pNonMoveableDataInBase = rhs.m_pNonMoveableDataInBase;
  
          return *this;
      }
  
  private:
      //this private member swaps the data members' contents.
      //It is private because it isn't virtual and only swaps the base contents and is thus not safe as a public interface
      void Swap(Base&amp; other)
      {
          std::swap(m_moveableDataInBase, other.m_moveableDataInBase);
          std::swap(m_pNonMoveableDataInBase, other.m_pNonMoveableDataInBase);
      }
  
      //an example of some large blob of data which we would like to move instead of copy for performance reasons.
      //normally, I would have used a unique_ptr but this is default moveable and I need an example of something that isn't
      BlobA* m_moveableDataInBase{ new BlobA };
  
      //an example of some data that we can't or don't want to move
      int m_pNonMoveableDataInBase = 123;
  };
  
  //----------------------------------------
  
  class Derived : public Base
  {
  public:
  
      //Default construct the Derived class, this is called after the base class constructor
      //C++11 allows the data members to initialised, where declared. Otherwise you would do it here.
      Derived()
      {
  
      }
  
      //Default virtual destructor, to clean up stuff that can't be done automatically through RAII
      virtual ~Derived()
      {
          delete m_pMoveableDataInDerived; //this is a contrived example to show non-default moveable data, in practice RAII should be used rather than deletes like this
      }
  
      //Copy constructor, needs to accept a const ref to another derived class with which it
      //first copy constructs the base and then copies the derived data members
      Derived(const Derived&amp; other) :
      Base(other),  // forward to the base copy constructor
      m_pMoveableDataInDerived(new BlobB(*other.m_pMoveableDataInDerived)),  // copy the other's moveable data
      m_pNonMoveableDataInDerived(other.m_pNonMoveableDataInDerived)         // copy the other's non-moveable data
      {
  
      }
  
      //Assignment operator uses the canonical copy then swap idiom. It returns a reference to allow chaining: a = b = c
      //Because it uses the derived copy constructor, which in turn copy constructs the base, we don't forward to the base assignment operator.
      Derived&amp; operator=(const Derived&amp; rhs)
      {
          Derived temp(rhs);
          Swap(temp);
          return *this;
      }
  
      //The move construtor is declared as throwing no eceptions so that it will be called by STL algorithms
      //It accepts an rvalue and first moves the Base part and then the Derived part.
      //There is no point in allocating any resource before moving so in this example, m_pBlobB is set to nullptr
      Derived(Derived&amp;&amp; other) noexcept
      : Base(std::move(other)), // forward to base move constructor
      m_pMoveableDataInDerived(nullptr) // don't bother allocating our own resources to moveable data because we are about to move (steal) the other's resource
      {
          Swap(other);
      }
  
      //The move assignment operator is declared as throwing no exceptions so that it will be called by STL algorithms
      //It accepts an rvalue and first calls the base assignment operator and then moves the data resources from the rhs using swap
      Derived&amp; operator=(Derived&amp;&amp; rhs) noexcept
      {
          //forward to the base move operator=
          Base::operator=(std::move(rhs));
  
          //move (steal) the moveable contents from rhs
          std::swap(m_pMoveableDataInDerived, rhs.m_pMoveableDataInDerived);
  
          //copy the non-moveable contents from rhs
          m_pNonMoveableDataInDerived = rhs.m_pNonMoveableDataInDerived;
      }
  
  private:
      //this member swaps the Derived data members contents.
      //It is private because it doesn't swap the base contents and is thus not safe as a public interface
      void Swap(Derived&amp; other) noexcept
      {
          std::swap(m_pMoveableDataInDerived, other.m_pMoveableDataInDerived);
          std::swap(m_pNonMoveableDataInDerived, other.m_pNonMoveableDataInDerived);
      }
  
      //an example of some large blob of data which we would like to move instead of copy for performance reasons.
      //normally, I would have used a unique_ptr but this is default moveable and I need an example of something that isn't
      BlobB* m_pMoveableDataInDerived{ new BlobB };
  
      //an example of some data that we can't or don't want to move
      int m_pNonMoveableDataInDerived = 456;
  };
  </code></pre>