I am looking for an intuitive and extensible way to implement factories for subclasses of a given base class in c++. I want to provide such a factory function in a library.T
My comments were probably not very clear. So here is a C++11 "solution" relying on template meta programming : (Possibly not the nicest way of doing this though)
#include
#include
// Type list stuff: (perhaps use an existing library here)
class EmptyType {};
template
struct TypeList
{
typedef T1 Head;
typedef T2 Tail;
};
template
struct MakeTypeList;
template
struct MakeTypeList
{
typedef TypeList Type;
};
template
struct MakeTypeList
{
typedef TypeList::Type > Type;
};
// Calling produce
template
struct Producer;
template
struct Producer
{
template
static BaseType* Produce(Args... args)
{
return nullptr;
}
};
template
struct Producer, BaseType>
{
template
static BaseType* Produce(Args... args)
{
BaseType* b = Head::Produce(args...);
if(b != nullptr)
return b;
return Producer::Produce(args...);
}
};
// Generic AbstractFactory:
template
struct AbstractFactory {
typedef Producer ProducerType;
template
static BaseType* Produce(Args... args)
{
return ProducerType::Produce(args...);
}
};
class Base {}; // Example base class you had
struct Derived0 : public Base { // Example derived class you had
Derived0() = default;
static Base* Produce(int value)
{
if(value == 0)
return new Derived0();
return nullptr;
}
};
struct Derived1 : public Base { // Another example class
Derived1() = default;
static Base* Produce(int value)
{
if(value == 1)
return new Derived1();
return nullptr;
}
};
int main()
{
// This will be our abstract factory type:
typedef AbstractFactory ::Type> Factory;
Base* b1 = Factory::Produce(1);
Base* b0 = Factory::Produce(0);
Base* b2 = Factory::Produce(2);
// As expected b2 is nullptr
std::cout << b0 << ", " << b1 << ", " << b2 << std::endl;
}
Advantages:
Disadvantages:
In the end, using the prototype design pattern might turn out better. I don't know since I haven't tried using my code.
I'd like to state some additional things (after further discussion on the chat):
Produce (static) member functions. You store the objects if and only if they're not the nullptr.