I need to implement a factory class in C ++, but when I thought about it, I discovered one big problem that I could not solve, and I found out that all examples of factory implementation are just as wrong. Maybe I'm wrong, but please tell me why.
So, here is a simple βtypicalβ factory implementation, it allows me to register new objects without changing the factory class.
//fruit.h class Fruit { protected : int count; public : Fruit(int count) : count(count) {} virtual void show() = 0; }; // factory.h /** singleton factory */ class Factory { typedef Fruit* (*FruitCreateFunction)(int); static Factory* factory; std::map<std::string, FruitCreateFunction> registeredFruits; public : static Factory& instance() { if (factory == NULL) factory = new Factory(); return *factory; } bool registerFruit(const std::string& name, Fruit* (createFunction)(int)) { registeredFruits.insert(std::make_pair(name, createFunction)); return true; } Fruit* createFruit(const std::string& name, int count) { return registeredFruits[name](count); } }; //factory.cpp Factory* Factory::factory = NULL; //apple.h class Apple : public Fruit { static Fruit* create(int count) { return new Apple(count); } Apple(int count) : Fruit(count) {} virtual void show() { printf("%d nice apples\n", count); }; static bool registered; }; // apple.cpp bool Apple::registered = Factory::instance().registerFruit("apple", Apple::create); //banana.h class Banana : public Fruit { static Fruit* create(int count) { return new Banana(count); } Banana(int count) : Fruit(count) {} virtual void show() { printf("%d nice bananas\n", count); }; static bool registered; }; // banana.cpp bool Banana::registered = Factory::instance().registerFruit("banana", Banana::create); // main.cpp int main(void) { std::vector<Fruit*> fruits; fruits.push_back(Factory::instance().createFruit("apple", 10)); fruits.push_back(Factory::instance().createFruit("banana", 7)); fruits.push_back(Factory::instance().createFruit("apple", 6)); for (size_t i = 0; i < fruits.size(); i++) { fruits[i]->show(); delete fruits[i]; } return 0; }
Ok, this code looks fancy and it works, but here it goes but:
The C ++ standard does not allow me to determine the order in which global (static) variables will be defined.
I have 3 static variables here
Apple::registered; Banana::registered; Factory::factory;
The Factory::factory pointer must be NULL before the registered variable Apple (or Banana) :: or the Factory::instance method will work with an uninitialized value and behave unpredictably.
So what I will not get here? Does the code really work only by chance? If so, how do I solve the problem?