Composition or inheritance

| Home | Libraries | People | FAQ | More

## Composition or inheritance

For classes made up of other classes (via either composition or inheritance), the move constructor and move assignment can be easily coded using the `boost::move` function:

    class Base
    {
       BOOST_COPYABLE_AND_MOVABLE(Base)

       public:
       Base(){}

       Base(const Base &/*x*/) {/**/}            // Copy ctor

       Base(BOOST_RV_REF(Base) /*x*/) {/**/}     // Move ctor

       Base& operator=(BOOST_RV_REF(Base) /*x*/)
       {/**/ return *this;}                      // Move assign

       Base& operator=(BOOST_COPY_ASSIGN_REF(Base) /*x*/)
       {/**/ return *this;}                      // Copy assign

       virtual Base *clone() const
       {  return new Base(*this);  }

       virtual ~Base(){}
    };

    class Member
    {
       BOOST_COPYABLE_AND_MOVABLE(Member)

       public:
       Member(){}

       // Compiler-generated copy constructor...

       Member(BOOST_RV_REF(Member))  {/**/}      // Move ctor

       Member &operator=(BOOST_RV_REF(Member))   // Move assign
       {/**/ return *this;  }

       Member &operator=(BOOST_COPY_ASSIGN_REF(Member))   // Copy assign
       {/**/ return *this;  }
    };

    class Derived : public Base
    {
       BOOST_COPYABLE_AND_MOVABLE(Derived)
       Member mem_;

       public:
       Derived(){}

       // Compiler-generated copy constructor...

       Derived(BOOST_RV_REF(Derived) x)             // Move ctor
          : Base(BOOST_MOVE_BASE(Base, x)),
            mem_(boost::move(x.mem_)) { }

       Derived& operator=(BOOST_RV_REF(Derived) x)  // Move assign
       {
          Base::operator=(BOOST_MOVE_BASE(Base, x));
          mem_ = boost::move(x.mem_);
          return *this;
       }

       Derived& operator=(BOOST_COPY_ASSIGN_REF(Derived) x)  // Copy assign
       {
          Base::operator=(x);
          mem_  = x.mem_;
          return *this;
       }
       // ...
    };

| Important
Due to limitations in the emulation code, a cast to `Base &` is needed before moving the base part in the move constructor and call Base's move constructor instead of the copy constructor.

Each subobject will now be treated individually, calling move to bind to the subobject's move constructors and move assignment operators. `Member` has move operations coded (just like our earlier `clone_ptr` example) which will completely avoid the tremendously more expensive copy operations:

    Derived d;
    Derived d2(boost::move(d));
    d2 = boost::move(d);

Note above that the argument x is treated as a lvalue reference. That's why it is necessary to say `move(x)` instead of just x when passing down to the base class. This is a key safety feature of move semantics designed to prevent accidently moving twice from some named variable. All moves from lvalues occur explicitly.