Advertisement
Guest User

Const Correctness with smart pointers and containers

a guest
Jan 9th, 2012
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.48 KB | None | 0 0
  1. #include <memory>
  2. #include <vector>
  3. #include <iostream>
  4. #include <common.h>
  5.  
  6.     class Shape;
  7.  
  8.     typedef std::unique_ptr<Shape> shape_ptr;
  9.  
  10.     class Shape{
  11.  
  12.         public:
  13.             Shape(){};
  14.             virtual ~Shape(){std::cout << "Shape destructor: " << this << std::endl;};
  15.  
  16.             virtual void draw() const = 0;
  17.             virtual float area() const = 0;
  18.             virtual float doSomething() = 0;
  19.             virtual float doThat() const = 0;
  20.  
  21.             virtual shape_ptr clone() const = 0;
  22.             virtual shape_ptr create() const = 0;
  23.     };
  24.  
  25.     class Rectangle:public Shape{
  26.         public:
  27.  
  28.             Rectangle(int height=0, int width=0):m_Height(height),m_Width(width){};
  29.             ~Rectangle(){};
  30.  
  31.             virtual void draw() const;
  32.             virtual float area() const;
  33.             virtual float doSomething();
  34.             virtual float doThat() const;
  35.  
  36.             virtual shape_ptr clone() const{ return shape_ptr(new Rectangle(*this)); };
  37.             virtual shape_ptr create() const{ return shape_ptr(new Rectangle()); };
  38.  
  39.         private:
  40.             int m_Height;
  41.             int m_Width;
  42.     };
  43.  
  44.  
  45.     class Circle:public Shape{
  46.         public:
  47.  
  48.             Circle(float radius=0):m_Radius(radius){};
  49.             Circle(const Circle & other):m_Radius(other.m_Radius){};
  50.             ~Circle(){std::cout << "Circle destructor: " << this << std::endl; };
  51.  
  52.             virtual void draw() const;
  53.             virtual float area() const;
  54.             virtual float doSomething();
  55.             virtual float doThat() const;
  56.  
  57.             virtual shape_ptr clone() const{ return shape_ptr(new Circle(*this)); };
  58.             virtual shape_ptr create() const{ return shape_ptr(new Circle()); };
  59.  
  60.         private:
  61.             float m_Radius;
  62.     };
  63.  
  64.     class ShapeInfo{
  65.  
  66.         public:
  67.  
  68.             typedef std::shared_ptr<Shape> ShapePtr;
  69.  
  70.             ShapeInfo(ShapePtr ptr, int id = 0):m_ShapePtr(ptr),m_nID(id){};
  71.             ShapeInfo( const ShapeInfo & refDesc):m_ShapePtr(refDesc.m_ShapePtr),m_nID(refDesc.m_nID){};
  72.             ~ShapeInfo(){std::cout << "ShapeInfo destructor!" << std::endl; }
  73.  
  74.             void swap( ShapeInfo & );
  75.             ShapeInfo operator = ( ShapeInfo );
  76.  
  77.             void draw() const{ m_ShapePtr->draw(); };
  78.             float area() const{ return m_ShapePtr->area(); };
  79.             float doSomething(){ return m_ShapePtr->doSomething(); };
  80.             float doThat(){ return m_ShapePtr->doThat(); };
  81.  
  82.         private:
  83.  
  84.             ShapePtr m_ShapePtr;
  85.             int m_nID;
  86.    
  87.     };
  88.  
  89.     class ShapeContainerInfo{
  90.  
  91.         public:
  92.  
  93.             typedef std::vector<ShapeInfo> ShapeContainer;
  94.  
  95.             ShapeContainerInfo( ){ std::cout << "ShapeContainerNew Default constructor" << std::endl; };
  96.             ShapeContainerInfo( ShapeContainerInfo && other):m_vect(std::move(other.m_vect)){ std::cout << "ShapeContainerNew Move constructor" << std::endl; };
  97.             ShapeContainerInfo( const ShapeContainerInfo & other ):m_vect(other.m_vect){ std::cout << "ShapeContainerNew Reference constructor" << std::endl; };
  98.             ~ShapeContainerInfo(){ std::cout << "ShapeContainerNew destructor" << std::endl; };
  99.  
  100.             const ShapeInfo & operator []( int ) const;
  101.             //ShapeInfo & operator []( int );
  102.  
  103.             void swap(ShapeContainerInfo & );
  104.             ShapeContainerInfo & operator = (ShapeContainerInfo );
  105.  
  106.             int size() const{ return static_cast<int>(m_vect.size()); };
  107.  
  108.             friend ShapeContainerInfo createBasicShapesInfo();
  109.             friend ShapeContainerInfo createComplexShapesInfo();
  110.  
  111.         private:
  112.             ShapeContainer m_vect;
  113.     };
  114.  
  115.     class ShapeContainer{
  116.  
  117.         public:
  118.  
  119.             //typedef std::unique_ptr<Shape> ShapePtr;
  120.             typedef std::shared_ptr<Shape> ShapePtr;
  121.             typedef std::vector<ShapePtr> ShapePtrContainer;
  122.  
  123.             ShapeContainer(){};
  124.             ShapeContainer( ShapeContainer && );
  125.             ShapeContainer( const ShapeContainer & );
  126.             ~ShapeContainer(){};
  127.  
  128.             const ShapePtr & at( int ) const;
  129.             const ShapePtr & operator[]( int ) const;
  130.             //ShapePtr & operator[]( int );
  131.  
  132.             ShapeContainer & operator = (ShapeContainer&&);
  133.             int size() const{ return static_cast<int>(m_vect.size()); };
  134.  
  135.             friend ShapeContainer createBasicShapes();
  136.             friend ShapeContainer createComplexShapes();
  137.  
  138.             friend void swap(ShapeContainer& x, ShapeContainer& y) {x.m_vect.swap(y.m_vect);}
  139.  
  140.         private:
  141.  
  142.             ShapePtrContainer m_vect;
  143.     };
  144.    
  145.         void Rectangle::draw() const{
  146.         std::cout << "draw rectangle at address: " << this << std::endl;
  147.     }
  148.  
  149.     float Rectangle::area() const{
  150.         float area = static_cast<float>(m_Height*m_Width);
  151.         std::cout << "this is the Rectangle's area: " << area << std::endl;
  152.         return area;
  153.     }
  154.  
  155.     float Rectangle::doSomething(){
  156.         std::cout << "Rectangle doing Something!" << std::endl;
  157.         return (1.0);
  158.     }
  159.  
  160.     float Rectangle::doThat() const {
  161.         std::cout << "Rectangle doThat!" << std::endl;
  162.         return (1.0);
  163.     }
  164.  
  165.     /////////////////////////////////////////////////////////////////
  166.  
  167.     void Circle::draw() const{
  168.         std::cout << "draw circle at address: " << this << std::endl;
  169.     }
  170.  
  171.     float Circle::area() const{
  172.         float area = static_cast<float>(m_Radius*2*3.1415);
  173.         std::cout << "this is the Circle's area: " << area << std::endl;
  174.         return area;
  175.     }
  176.  
  177.     float Circle::doSomething(){
  178.         std::cout << "Circle doing Something!" << std::endl;
  179.         return (1.0);
  180.     }
  181.  
  182.     float Circle::doThat() const{
  183.         std::cout << "Circle doThat!" << std::endl;
  184.         return (1.0);
  185.     }
  186.  
  187.     /////////////////////////////////////////////////////////////////
  188.  
  189.     void ShapeInfo::swap( ShapeInfo & elem ){
  190.  
  191.         using std::swap;
  192.        
  193.         swap(m_ShapePtr, elem.m_ShapePtr);
  194.         swap(m_nID, elem.m_nID);
  195.     }
  196.  
  197.     ShapeInfo ShapeInfo::operator = ( ShapeInfo other ){
  198.  
  199.         other.swap(*this);
  200.         return (*this);
  201.     }
  202.  
  203.     /////////////////////////////////////////////////////////////////
  204.  
  205.     /*
  206.     inline const ShapeInfo & ShapeContainerNew::at( int index ) const{
  207.         return m_vect[index];
  208.     }*/
  209.  
  210.     void ShapeContainerInfo::swap( ShapeContainerInfo & other ){
  211.         using std::swap;
  212.         swap(m_vect, other.m_vect);
  213.     }
  214.  
  215.     ShapeContainerInfo & ShapeContainerInfo::operator = (ShapeContainerInfo other ){
  216.         other.swap(*this);
  217.         return (*this);
  218.     }
  219.  
  220.     ShapeContainerInfo createBasicShapesInfo(){
  221.         ShapeContainerInfo cont;
  222.         cont.m_vect.push_back( ShapeInfo( ShapeInfo::ShapePtr(new Circle()), 0) );
  223.         cont.m_vect.push_back( ShapeInfo( ShapeInfo::ShapePtr(new Rectangle()), 1) );
  224.         return cont;
  225.     }
  226.  
  227.     ShapeContainerInfo createComplexShapesInfo(){
  228.         ShapeContainerInfo cont;
  229.         cont.m_vect.push_back( ShapeInfo( ShapeInfo::ShapePtr(new Rectangle()), 3) );
  230.         return cont;
  231.     }
  232.  
  233.     const ShapeInfo & ShapeContainerInfo::operator []( int index ) const{
  234.         std::cout << "const ShapeContainerInfo::operator [] const" << std::endl;
  235.         return m_vect[index];
  236.     }
  237.  
  238.     /*
  239.     ShapeInfo & ShapeContainerInfo::operator []( int index ){
  240.         std::cout << "const ShapeContainerInfo::operator [] const" << std::endl;
  241.         return m_vect[index];
  242.     }*/
  243.  
  244.     /////////////////////////////////////////////////////////////////
  245.  
  246.     ShapeContainer::ShapeContainer(ShapeContainer && other)
  247.         :m_vect(std::move(other.m_vect))
  248.     {
  249.    
  250.     }
  251.  
  252.     ShapeContainer & ShapeContainer::operator = (ShapeContainer&& other){
  253.         m_vect = std::move(other.m_vect);
  254.         return (*this);
  255.     }
  256.  
  257.     ShapeContainer::ShapeContainer( const ShapeContainer & other ){
  258.  
  259.         for(int i=0; i<(int)other.m_vect.size(); i++){
  260.             m_vect.push_back( ShapePtr( other.m_vect[i] ? other.m_vect[i]->clone() : nullptr )  );
  261.         }
  262.  
  263.         /*
  264.         auto begin = other.m_vect.begin();
  265.         auto end = other.m_vect.end();
  266.         std::transform(begin, end, std::back_inserter(m_vect), [](ShapePtr const& p)
  267.         { return p->clone(); });
  268.         */
  269.  
  270.         /*
  271.         for(auto&& p: other.m_vect) {
  272.             m_vect.push_back(p->clone());
  273.         }*/
  274.     }
  275.  
  276.     ShapeContainer createBasicShapes(){
  277.         ShapeContainer cont;
  278.         cont.m_vect.push_back(ShapeContainer::ShapePtr(new Circle()));
  279.         cont.m_vect.push_back(ShapeContainer::ShapePtr(new Rectangle()));
  280.         return cont;
  281.     }
  282.  
  283.     ShapeContainer createComplexShapes(){
  284.         ShapeContainer cont;
  285.         cont.m_vect.push_back(ShapeContainer::ShapePtr(new Rectangle()));
  286.         return cont;
  287.     }
  288.  
  289.     const ShapeContainer::ShapePtr & ShapeContainer::at( int index ) const{
  290.         std::cout << "const ShapeContainer::at(index) const" << std::endl;
  291.         return m_vect[index];
  292.     }
  293.  
  294.     const ShapeContainer::ShapePtr & ShapeContainer::operator[]( int index ) const{
  295.         std::cout << "const ShapeContainer::operator[] const" << std::endl;
  296.         return m_vect[index];
  297.     }
  298.    
  299.     int main(int argc, char ** argv){
  300.  
  301.  
  302.         ShapeContainer container1 = createBasicShapes();
  303.         for (int i =0; i < container1.size(); i++){
  304.             float tmp = container1[i]->doSomething();
  305.         }
  306.  
  307.         ShapeContainerInfo container2 = createBasicShapesInfo();
  308.         for (int i =0; i < container2.size(); i++){
  309.             std::cout << i << std::endl;
  310.             float tmp = container2[i].doSomething();
  311.             //float tmp = container2.m_vect[i].doSomething();
  312.         }
  313.      
  314.         return (EXIT_SUCCESS);
  315.  
  316.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement