Skip to content

Instantly share code, notes, and snippets.

@facontidavide
Last active November 16, 2022 09:16
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save facontidavide/c2d0fe6a29dc1e344e17799309ac2f1c to your computer and use it in GitHub Desktop.
Save facontidavide/c2d0fe6a29dc1e344e17799309ac2f1c to your computer and use it in GitHub Desktop.
Factory pattern in C++
#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();
}
/* expectd output:
Registering class 'Circle'
Registering class 'Square'
Registering class 'Ellipse'
drawing a circle
drawing a square
drawing an ellipse
*/
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment