move/example/doc_clone_ptr.cpp
2014-11-01 19:32:36 +01:00

158 lines
3.5 KiB
C++

//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/move for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/move/detail/config_begin.hpp>
#include <boost/move/utility_core.hpp>
//[clone_ptr_base_derived
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;
}
// ...
};
//]
//[clone_ptr_def
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;
}
};
//]
int main()
{
{
//[copy_clone_ptr
clone_ptr<Base> p1(new Derived());
// ...
clone_ptr<Base> p2 = p1; // p2 and p1 each own their own pointer
//]
}
{
//[move_clone_ptr
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
}
//]
//[clone_ptr_move_derived
Derived d;
Derived d2(boost::move(d));
d2 = boost::move(d);
//]
return 0;
}
#include <boost/move/detail/config_end.hpp>