jack06215
8/21/2017 - 3:38 AM

C++ factory design pattern

C++ factory design pattern

#include <iostream>
#include <unordered_map>
#include <functional>
#include <vector>

// Base class
class Shape 
{
  public:
    virtual void draw() = 0;
};

// Factory class
class ShapeFactory 
{
  public:
    typedef std::unordered_map<std::string, std::function<Shape*()>> registry_map;

    // use this to instantiate the proper Derived class
    static Shape * instantiate(const std::string& name)
    {
      auto it = ShapeFactory::registry().find(name);
      return it == ShapeFactory::registry().end() ? nullptr : (it->second)();
    }

    static registry_map & registry()
    {
      static registry_map impl;
      return impl;
    }

};

template<typename T> struct ShapeFactoryRegister
{
    ShapeFactoryRegister(std::string name)
    {
      ShapeFactory::registry()[name] = []() { return new T; };
      std::cout << "Registering class '" << name << "'\n";
    }
};


class Circle : public Shape 
{
  public:
    void draw() {  std::cout << "drawing a circle " <<std::endl;  }
  private:
    static ShapeFactoryRegister<Circle> AddToFactory_;
};

ShapeFactoryRegister<Circle> Circle::AddToFactory_("Circle" );

//------------------

class Square : public Shape 
{
  public:
    void draw() {  std::cout << "drawing a square " <<std::endl;  }
  private:
    static ShapeFactoryRegister<Square> AddToFactory_;
};

ShapeFactoryRegister<Square> Square::AddToFactory_("Square" );



class Ellipse : public Shape 
{
  public:
    void draw() {  std::cout << "drawing an ellipse " <<std::endl;  }
  private:
    static ShapeFactoryRegister<Ellipse> AddToFactory_;
};

ShapeFactoryRegister<Ellipse> Ellipse::AddToFactory_("Ellipse" );




int main(int argc, char *argv[])
{
  std::vector<Shape*> shapes;

  shapes.push_back( ShapeFactory::instantiate("Circle") );
  shapes.push_back( ShapeFactory::instantiate("Square") );
  shapes.push_back( ShapeFactory::instantiate("Ellipse") );

  for (auto& shape: shapes){
    shape->draw();
  }
  return 0;
}