Last active
November 16, 2022 09:16
-
-
Save facontidavide/c2d0fe6a29dc1e344e17799309ac2f1c to your computer and use it in GitHub Desktop.
Factory pattern in C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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