-
-
Save l4es/5f99a7c187d3b70927a02a83b3111fb4 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