class Shape; typedef std::unique_ptr shape_ptr; class Shape{ public: Shape(){}; virtual ~Shape(){}; virtual void draw() const = 0; virtual float area() const = 0; virtual shape_ptr clone() const = 0; virtual shape_ptr create() const = 0; }; class Rectangle:public Shape{ public: Rectangle(int height=0, int width=0):m_Height(height),m_Width(width){}; ~Rectangle(){}; virtual void draw() const; virtual float area() const; virtual shape_ptr clone() const{ return shape_ptr(new Rectangle(*this)); }; virtual shape_ptr create() const{ return shape_ptr(new Rectangle()); }; private: int m_Height; int m_Width; }; class Circle:public Shape{ public: Circle(float radius=0):m_Radius(radius){}; ~Circle(){}; virtual void draw() const; virtual float area() const; virtual shape_ptr clone() const{ return shape_ptr(new Circle(*this)); }; virtual shape_ptr create() const{ return shape_ptr(new Circle()); }; private: float m_Radius; }; class ShapeContainer{ public: typedef std::unique_ptr ShapePtr; typedef std::vector ShapePtrContainer; ShapeContainer(){}; ShapeContainer( ShapeContainer && ); ShapeContainer( const ShapeContainer & ); ~ShapeContainer(){}; const ShapePtr & at(int ) const; ShapeContainer & operator = (ShapeContainer&&); int size() const{ return static_cast(m_vect.size()); }; friend ShapeContainer createBasicShapes(); friend ShapeContainer createComplexShapes(); friend void swap(ShapeContainer& x, ShapeContainer& y) {x.m_vect.swap(y.m_vect);} private: ShapePtrContainer m_vect; }; class FooObj{ public: FooObj(){}; FooObj ( FooObj && ); FooObj( const ShapeContainer & ); FooObj ( const FooObj & ); ~FooObj(){}; FooObj & operator = (FooObj && ); void drawShapes() const; private: ShapeContainer m_container; }; class FooRef{ public: typedef std::unique_ptr uptr; FooRef(){}; FooRef( const ShapeContainer & ); FooRef( const FooRef & ); ~FooRef(){}; FooRef & operator = (const FooRef & ); void drawShapes() const; private: uptr m_container; }; void Rectangle::draw() const{ std::cout << "draw rectangle at address: " << this << std::endl; } float Rectangle::area() const{ float area = static_cast(m_Height*m_Width); std::cout << "this is the Rectangle's area: " << area << std::endl; return area; } void Circle::draw() const{ std::cout << "draw circle at address: " << this << std::endl; } float Circle::area() const{ float area = static_cast(m_Radius*2*3.1415); std::cout << "this is the Circle's area: " << area << std::endl; return area; } ShapeContainer::ShapeContainer(ShapeContainer && other) :m_vect(std::move(other.m_vect)) { } ShapeContainer & ShapeContainer::operator = (ShapeContainer&& other){ m_vect = std::move(other.m_vect); return (*this); } ShapeContainer::ShapeContainer( const ShapeContainer & other ){ for(int i=0; i<(int)other.m_vect.size(); i++){ m_vect.push_back(other.m_vect[i]->clone()); } } ShapeContainer createBasicShapes(){ ShapeContainer cont; cont.m_vect.push_back(ShapeContainer::ShapePtr(new Circle())); cont.m_vect.push_back(ShapeContainer::ShapePtr(new Rectangle())); return cont; } ShapeContainer createComplexShapes(){ ShapeContainer cont; cont.m_vect.push_back(ShapeContainer::ShapePtr(new Rectangle())); return cont; } const ShapeContainer::ShapePtr & ShapeContainer::at( int index ) const{ return m_vect[index]; } FooObj::FooObj( const ShapeContainer & cont ) :m_container(cont) { } FooObj::FooObj( const FooObj & other) :m_container(other.m_container) { } FooObj & FooObj::operator = ( FooObj && other ){ m_container = std::move(other.m_container); return (*this); } void FooObj::drawShapes() const{ for(int i=0; i < m_container.size(); i++){ m_container.at(i)->draw(); } } FooRef::FooRef( const ShapeContainer & shapec ) :m_container( uptr(new ShapeContainer(shapec))) { } void FooRef::drawShapes() const{ for(int i=0; i < m_container->size(); i++){ m_container->at(i)->draw(); } } int main(int argc, char ** argv){ ShapeContainer mycontainer = createBasicShapes(); cout << "hi" << endl; FooObj myfoo(createBasicShapes()); myfoo.drawShapes(); FooObj myfoo2 = myfoo; myfoo2.drawShapes(); return (EXIT_SUCCESS); }