Boost C++ 函式庫

...世界上評價最高且設計最專業的 C++ 函式庫專案之一。 Herb SutterAndrei Alexandrescu,《C++ Coding Standards》(C++ 程式碼規範)

PrevUpHomeNext

組合或繼承

對於由其他類別組成(透過組合或繼承)的類別,可以使用 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;
   }
   // ...
};
[Important] 重要

由於模擬程式碼的限制,在移動建構函式中移動基底類別部分之前,需要強制轉型為 Base &,並呼叫基底類別的移動建構函式而不是複製建構函式。

現在每個子物件將被單獨處理,呼叫 move 來綁定到子物件的移動建構函式和移動賦值運算子。Member 已編碼移動操作(就像我們之前的 clone_ptr 範例一樣),這將完全避免成本高昂的複製操作。

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

請注意,上面的參數 x 被視為左值參考。這就是為什麼在傳遞給基底類別時需要使用 move(x) 而不是僅使用 x 的原因。這是移動語義的一個關鍵安全特性,旨在防止意外地從某些命名變數移動兩次。所有從左值的移動都是顯式發生的。


PrevUpHomeNext