Graeme
Graeme

Reputation: 4592

C++ Generic Abstract Factory Design Question

I'm currently trying to design an generic Abstract Factory and have the following class design sketched out:

template <typename T>
class TFactory
{
    public:
        template <typename A>
        static T* create(A a);

        template <typename A, typename B>
        static T* create(A a, B b);

        template <typename A, typename B, typename C>
        static T* create(A a, B b, C c);

        static T* destory(T* ptr);
};

The factory can then be used as so:

Factory<MyType>::create(1, "hello");
Factory<MyType>::create<short, const std::string&>(1, "hello");

Is there a better way to design this? This seems better than varargs but still has me overloading for up to 10 functions.

EDIT:

I should add the reason for this is that I will be using a custom memory allocator within the Factory.

Upvotes: 0

Views: 946

Answers (3)

Alexandre C.
Alexandre C.

Reputation: 56956

Without variadic templates, there is not much you can do (except preprocessor abuse, but I can't see a way to do this cleanly, ie. without code generators).

Have a look at boost::make_shared if you intend to not reinvent the wheel.

By the way, this is not an abstract factory. Abstract factories are polymorphic classes.

Upvotes: 1

James
James

Reputation: 5425

Sounds like what you are looking for is Varardic Templates, which will be introduced as part of the C++0x standard.

Upvotes: 1

Mikael Persson
Mikael Persson

Reputation: 18572

You can find this kind of work already done in Boost libraries such as Bind and Lambda.

Here is a list of Lambda expressions that wrap constructors/destructors and new/delete. You can either use those, or get inspired by them to write your own.

For example, using Lambda constructor, you could have the following:

template <typename T> class TFactory {
    public:
        template <typename A>
        static T* create(A a) {
          return new a(); //where a wraps a binded constructor call.
        }; 
};

Then you would use the create function as follows:

Factory<MyType>::create(boost::bind(boost::lambda::constructor<MyType>(),1,"hello"));

I'm sure you can find a way to make this look nicer (maybe with a #define).

Upvotes: 1

Related Questions