1 ////////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Ion Gaztanaga 2009. 4 // Distributed under the Boost Software License, Version 1.0. 5 // (See accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt) 7 // 8 // See http://www.boost.org/libs/move for documentation. 9 // 10 ////////////////////////////////////////////////////////////////////////////// 11 #include <boost/move/utility_core.hpp> 12 13 //[clone_ptr_base_derived 14 class Base 15 { 16 BOOST_COPYABLE_AND_MOVABLE(Base) 17 18 public: Base()19 Base(){} 20 Base(const Base &)21 Base(const Base &/*x*/) {/**/} // Copy ctor 22 Base(BOOST_RV_REF (Base))23 Base(BOOST_RV_REF(Base) /*x*/) {/**/} // Move ctor 24 operator =(BOOST_RV_REF (Base))25 Base& operator=(BOOST_RV_REF(Base) /*x*/) 26 {/**/ return *this;} // Move assign 27 operator =(BOOST_COPY_ASSIGN_REF (Base))28 Base& operator=(BOOST_COPY_ASSIGN_REF(Base) /*x*/) 29 {/**/ return *this;} // Copy assign 30 clone() const31 virtual Base *clone() const 32 { return new Base(*this); } 33 ~Base()34 virtual ~Base(){} 35 }; 36 37 class Member 38 { 39 BOOST_COPYABLE_AND_MOVABLE(Member) 40 41 public: Member()42 Member(){} 43 44 // Compiler-generated copy constructor... 45 Member(BOOST_RV_REF (Member))46 Member(BOOST_RV_REF(Member)) {/**/} // Move ctor 47 operator =(BOOST_RV_REF (Member))48 Member &operator=(BOOST_RV_REF(Member)) // Move assign 49 {/**/ return *this; } 50 operator =(BOOST_COPY_ASSIGN_REF (Member))51 Member &operator=(BOOST_COPY_ASSIGN_REF(Member)) // Copy assign 52 {/**/ return *this; } 53 }; 54 55 class Derived : public Base 56 { 57 BOOST_COPYABLE_AND_MOVABLE(Derived) 58 Member mem_; 59 60 public: Derived()61 Derived(){} 62 63 // Compiler-generated copy constructor... 64 Derived(BOOST_RV_REF (Derived)x)65 Derived(BOOST_RV_REF(Derived) x) // Move ctor 66 : Base(BOOST_MOVE_BASE(Base, x)), 67 mem_(boost::move(x.mem_)) { } 68 operator =(BOOST_RV_REF (Derived)x)69 Derived& operator=(BOOST_RV_REF(Derived) x) // Move assign 70 { 71 Base::operator=(BOOST_MOVE_BASE(Base, x)); 72 mem_ = boost::move(x.mem_); 73 return *this; 74 } 75 operator =(BOOST_COPY_ASSIGN_REF (Derived)x)76 Derived& operator=(BOOST_COPY_ASSIGN_REF(Derived) x) // Copy assign 77 { 78 Base::operator=(x); 79 mem_ = x.mem_; 80 return *this; 81 } 82 // ... 83 }; 84 //] 85 86 //[clone_ptr_def 87 template <class T> 88 class clone_ptr 89 { 90 private: 91 // Mark this class copyable and movable 92 BOOST_COPYABLE_AND_MOVABLE(clone_ptr) 93 T* ptr; 94 95 public: 96 // Construction clone_ptr(T * p=0)97 explicit clone_ptr(T* p = 0) : ptr(p) {} 98 99 // Destruction ~clone_ptr()100 ~clone_ptr() { delete ptr; } 101 clone_ptr(const clone_ptr & p)102 clone_ptr(const clone_ptr& p) // Copy constructor (as usual) 103 : ptr(p.ptr ? p.ptr->clone() : 0) {} 104 operator =(BOOST_COPY_ASSIGN_REF (clone_ptr)p)105 clone_ptr& operator=(BOOST_COPY_ASSIGN_REF(clone_ptr) p) // Copy assignment 106 { 107 if (this != &p){ 108 T *tmp_p = p.ptr ? p.ptr->clone() : 0; 109 delete ptr; 110 ptr = tmp_p; 111 } 112 return *this; 113 } 114 115 //Move semantics... clone_ptr(BOOST_RV_REF (clone_ptr)p)116 clone_ptr(BOOST_RV_REF(clone_ptr) p) //Move constructor 117 : ptr(p.ptr) { p.ptr = 0; } 118 operator =(BOOST_RV_REF (clone_ptr)p)119 clone_ptr& operator=(BOOST_RV_REF(clone_ptr) p) //Move assignment 120 { 121 if (this != &p){ 122 delete ptr; 123 ptr = p.ptr; 124 p.ptr = 0; 125 } 126 return *this; 127 } 128 }; 129 //] 130 main()131int main() 132 { 133 { 134 //[copy_clone_ptr 135 clone_ptr<Base> p1(new Derived()); 136 // ... 137 clone_ptr<Base> p2 = p1; // p2 and p1 each own their own pointer 138 //] 139 } 140 { 141 //[move_clone_ptr 142 clone_ptr<Base> p1(new Derived()); 143 // ... 144 clone_ptr<Base> p2 = boost::move(p1); // p2 now owns the pointer instead of p1 145 p2 = clone_ptr<Base>(new Derived()); // temporary is moved to p2 146 } 147 //] 148 //[clone_ptr_move_derived 149 Derived d; 150 Derived d2(boost::move(d)); 151 d2 = boost::move(d); 152 //] 153 return 0; 154 } 155