#include <list>
#include <functional>
#include <iostream>
template <typename AbstractProduct, typename ConcreteProduct>
inline AbstractProduct *abstractConstructor() {
return new ConcreteProduct();
}
template <typename Product>
class Factory {
public:
typedef std::function<Product *()> ConstructorType;
typedef std::list<ConstructorType> RegisteredList;
typedef typename RegisteredList::iterator iterator;
static Factory &instance() {
static Factory object;
return object;
}
bool add(ConstructorType constructor) {
mRegisteredList.push_back(constructor);
return true;
}
iterator begin() {
return mRegisteredList.begin();
}
iterator end() {
return mRegisteredList.end();
}
private:
RegisteredList mRegisteredList;
Factory() {};
Factory(const Factory &) = delete;
Factory &operator=(const Factory &) = delete;
};
////////////
// Plik register.h
class RegisteredBase // od tej klasy pochodzi dużo różnych klas
{
public:
virtual ~RegisteredBase() {}
virtual void WhoAmI()const=0; // tylko do demonstracji że to działa poprawnie
};
typedef Factory<RegisteredBase> Register;
// Plik A.h
class A:public RegisteredBase // jedna z tych "różnych klas
{
public:
A() {}
virtual void WhoAmI()const { std::cout<<"class A"<<std::endl; }
};
bool reg1 = Register::instance().add(&abstractConstructor<RegisteredBase, A>);
// Plik B.h
class B:public RegisteredBase // jeszcze jedna z tych "różnych klas
{
public:
B() {}
virtual void WhoAmI()const { std::cout<<"class B"<<std::endl; }
};
bool reg2 = Register::instance().add(&abstractConstructor<RegisteredBase, B>);
// Plik C.h
class C:public RegisteredBase // kolejna z tych "różnych klas
{
public:
C() {}
virtual void WhoAmI()const { std::cout<<"class C"<<std::endl; }
};
bool reg3 = Register::instance().add(&abstractConstructor<RegisteredBase, C>);
/////////////////////////
int main() {
std::list<RegisteredBase *> obj;
for(Register::iterator it = Register::instance().begin();
it != Register::instance().end();
++it) {
obj.push_back((*it)());
}
for(std::list<RegisteredBase *>::iterator it = obj.begin();
it != obj.end();
++it) {
(*it)->WhoAmI();
delete *it;
}
return 0;
}