Search code examples
c++objectconstructormovemove-semantics

Do move constructors need attribute that are moveable?


I am trying to wrap my head around move constructors and am hoping to get some more insights through this question. Here is a simple class.

class A
{
 private:
   vector<B> Bs;
 public:
   /*
   ..
   */

   A(A&& other)
   : Bs
   {
      Bs = other.Bs;
   }
}

Does my move constructor looks correct even if B does not have a move constructor? Will the move constructor be effective even if I haven't explicitly written a move assignment for the object of class B? If not, does it mean that if one wants to move any object, (s)he first have to ensure each attribute is also moveable?


Solution

  • If your object contains objects that are move-able (such as std::vector), the default move constructor will take care of the move, so you don't need to do anything. Try to use the Rule of Zero.

    In your case, no, the move ctor won't do the right thing. It will copy, since in

    Bs = other.Bs;
    

    other.Bs is a lvalue inside the function since it has a name (yes, it refers to a rvalue reference but other itself is a lvalue). You need

    Bs = std::move(other.Bs);
    

    or better

    A(A&& other) : Bs(std::move(other.Bs)) {}
    

    But again, in this case you really shouldn't write any user-defined move constructor at all.

    Highly recommended read from Howard Hinnant, the person who contributed probably the most to the concept of move semantics: http://www.slideshare.net/ripplelabs/howard-hinnant-accu2014