对于由其他类组成的类(通过组合或继承),可以使用 boost::move
函数轻松编写移动构造函数和移动赋值运算符。
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; } // ... };
重要提示 | |
---|---|
由于模拟代码的限制,在移动构造函数中移动基类部分之前,需要强制转换为 |
现在每个子对象都将被单独处理,调用 move 来绑定到子对象的移动构造函数和移动赋值运算符。Member
具有编码的移动操作(就像我们之前的 clone_ptr
示例一样),这将完全避免开销巨大的复制操作。
Derived d; Derived d2(boost::move(d)); d2 = boost::move(d);
请注意,上面的参数 x 被视为左值引用。这就是为什么在传递给基类时,必须使用 move(x)
而不是仅仅使用 x 的原因。这是移动语义的关键安全特性,旨在防止意外地从某个命名变量移动两次。所有来自左值的移动都显式发生。