doc_clone_ptr.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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/detail/config_begin.hpp>
  12. #include <boost/move/utility_core.hpp>
  13. //[clone_ptr_base_derived
  14. class Base
  15. {
  16. BOOST_COPYABLE_AND_MOVABLE(Base)
  17. public:
  18. Base(){}
  19. Base(const Base &/*x*/) {/**/} // Copy ctor
  20. Base(BOOST_RV_REF(Base) /*x*/) {/**/} // Move ctor
  21. Base& operator=(BOOST_RV_REF(Base) /*x*/)
  22. {/**/ return *this;} // Move assign
  23. Base& operator=(BOOST_COPY_ASSIGN_REF(Base) /*x*/)
  24. {/**/ return *this;} // Copy assign
  25. virtual Base *clone() const
  26. { return new Base(*this); }
  27. virtual ~Base(){}
  28. };
  29. class Member
  30. {
  31. BOOST_COPYABLE_AND_MOVABLE(Member)
  32. public:
  33. Member(){}
  34. // Compiler-generated copy constructor...
  35. Member(BOOST_RV_REF(Member)) {/**/} // Move ctor
  36. Member &operator=(BOOST_RV_REF(Member)) // Move assign
  37. {/**/ return *this; }
  38. Member &operator=(BOOST_COPY_ASSIGN_REF(Member)) // Copy assign
  39. {/**/ return *this; }
  40. };
  41. class Derived : public Base
  42. {
  43. BOOST_COPYABLE_AND_MOVABLE(Derived)
  44. Member mem_;
  45. public:
  46. Derived(){}
  47. // Compiler-generated copy constructor...
  48. Derived(BOOST_RV_REF(Derived) x) // Move ctor
  49. : Base(BOOST_MOVE_BASE(Base, x)),
  50. mem_(boost::move(x.mem_)) { }
  51. Derived& operator=(BOOST_RV_REF(Derived) x) // Move assign
  52. {
  53. Base::operator=(BOOST_MOVE_BASE(Base, x));
  54. mem_ = boost::move(x.mem_);
  55. return *this;
  56. }
  57. Derived& operator=(BOOST_COPY_ASSIGN_REF(Derived) x) // Copy assign
  58. {
  59. Base::operator=(x);
  60. mem_ = x.mem_;
  61. return *this;
  62. }
  63. // ...
  64. };
  65. //]
  66. //[clone_ptr_def
  67. template <class T>
  68. class clone_ptr
  69. {
  70. private:
  71. // Mark this class copyable and movable
  72. BOOST_COPYABLE_AND_MOVABLE(clone_ptr)
  73. T* ptr;
  74. public:
  75. // Construction
  76. explicit clone_ptr(T* p = 0) : ptr(p) {}
  77. // Destruction
  78. ~clone_ptr() { delete ptr; }
  79. clone_ptr(const clone_ptr& p) // Copy constructor (as usual)
  80. : ptr(p.ptr ? p.ptr->clone() : 0) {}
  81. clone_ptr& operator=(BOOST_COPY_ASSIGN_REF(clone_ptr) p) // Copy assignment
  82. {
  83. if (this != &p){
  84. T *tmp_p = p.ptr ? p.ptr->clone() : 0;
  85. delete ptr;
  86. ptr = tmp_p;
  87. }
  88. return *this;
  89. }
  90. //Move semantics...
  91. clone_ptr(BOOST_RV_REF(clone_ptr) p) //Move constructor
  92. : ptr(p.ptr) { p.ptr = 0; }
  93. clone_ptr& operator=(BOOST_RV_REF(clone_ptr) p) //Move assignment
  94. {
  95. if (this != &p){
  96. delete ptr;
  97. ptr = p.ptr;
  98. p.ptr = 0;
  99. }
  100. return *this;
  101. }
  102. };
  103. //]
  104. int main()
  105. {
  106. {
  107. //[copy_clone_ptr
  108. clone_ptr<Base> p1(new Derived());
  109. // ...
  110. clone_ptr<Base> p2 = p1; // p2 and p1 each own their own pointer
  111. //]
  112. }
  113. {
  114. //[move_clone_ptr
  115. clone_ptr<Base> p1(new Derived());
  116. // ...
  117. clone_ptr<Base> p2 = boost::move(p1); // p2 now owns the pointer instead of p1
  118. p2 = clone_ptr<Base>(new Derived()); // temporary is moved to p2
  119. }
  120. //]
  121. //[clone_ptr_move_derived
  122. Derived d;
  123. Derived d2(boost::move(d));
  124. d2 = boost::move(d);
  125. //]
  126. return 0;
  127. }
  128. #include <boost/move/detail/config_end.hpp>