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;
}