|  | Home | Libraries | People | FAQ | More | 
        Consider a simple handle class that owns a resource and also provides copy
        semantics (copy constructor and assignment). For example a clone_ptr might own a pointer, and call
        clone()
        on it for copying purposes:
      
template <class T> class clone_ptr { private: T* ptr; public: // construction explicit clone_ptr(T* p = 0) : ptr(p) {} // destruction ~clone_ptr() { delete ptr; } // copy semantics clone_ptr(const clone_ptr& p) : ptr(p.ptr ? p.ptr->clone() : 0) {} clone_ptr& operator=(const clone_ptr& p) { if (this != &p) { T *p = p.ptr ? p.ptr->clone() : 0; delete ptr; ptr = p; } return *this; } // move semantics clone_ptr(clone_ptr&& p) : ptr(p.ptr) { p.ptr = 0; } clone_ptr& operator=(clone_ptr&& p) { if(this != &p) { std::swap(ptr, p.ptr); delete p.ptr; p.ptr = 0; } return *this; } // Other operations... };
        clone_ptr has expected copy
        constructor and assignment semantics, duplicating resources when copying.
        Note that copy constructing or assigning a clone_ptr
        is a relatively expensive operation:
      
clone_ptr<Base> p1(new Derived()); // ... clone_ptr<Base> p2 = p1; // p2 and p1 each own their own pointer
        clone_ptr is code that you
        might find in today's books on C++, except for the part marked as move semantics.
        That part is implemented in terms of C++0x rvalue
        references. You can find some good
        introduction and tutorials on rvalue references in these papers:
      
        When the source of the copy is known to be a rvalue
        (e.g.: a temporary object), one can avoid the potentially expensive clone()
        operation by pilfering source's pointer (no one will notice!). The move constructor
        above does exactly that, leaving the rvalue in a default constructed state.
        The move assignment operator simply does the same freeing old resources.
      
        Now when code tries to copy a rvalue clone_ptr,
        or if that code explicitly gives permission to consider the source of the
        copy a rvalue (using boost::move),
        the operation will execute much faster.
      
clone_ptr<Base> p1(new Derived()); // ... clone_ptr<Base> p2 = boost::move(p1); // p2 now owns the pointer instead of p1 p2 = clone_ptr<Base>(new Derived()); // temporary is moved to p2 }
        Many aspects of move semantics can be emulated for compilers not supporting
        rvalue references
        and Boost.Move offers tools for that purpose.
        With Boost.Move we can write clone_ptr so that it will work both in
        compilers with rvalue references and those who conform to C++03. You just
        need to follow these simple steps:
      
BOOST_COPYABLE_AND_MOVABLE(classname)
          BOOST_COPY_ASSIGN_REF(classname)
          BOOST_RV_REF(classname)
          
        Let's see how are applied to clone_ptr:
      
template <class T> class clone_ptr { private: // Mark this class copyable and movable BOOST_COPYABLE_AND_MOVABLE(clone_ptr) T* ptr; public: // Construction explicit clone_ptr(T* p = 0) : ptr(p) {} // Destruction ~clone_ptr() { delete ptr; } clone_ptr(const clone_ptr& p) // Copy constructor (as usual) : ptr(p.ptr ? p.ptr->clone() : 0) {} clone_ptr& operator=(BOOST_COPY_ASSIGN_REF(clone_ptr) p) // Copy assignment { if (this != &p){ T *tmp_p = p.ptr ? p.ptr->clone() : 0; delete ptr; ptr = tmp_p; } return *this; } //Move semantics... clone_ptr(BOOST_RV_REF(clone_ptr) p) //Move constructor : ptr(p.ptr) { p.ptr = 0; } clone_ptr& operator=(BOOST_RV_REF(clone_ptr) p) //Move assignment { if (this != &p){ delete ptr; ptr = p.ptr; p.ptr = 0; } return *this; } };
      Question: What about types that don't own
      resources? (E.g. std::complex?)
    
No work needs to be done in that case. The copy constructor is already optimal.