Factories and conversion from Base to Derived...

W

werasm

Hi all,

I want to know whether the following is possible. I started out
with an idea called a CreationAbstractor. Basically just a
factory function wrapper for all types.

It looks like this:

template <class T>
class CreationAbstractor
{
public:
virtual T* create() const = 0;
virtual ~CreationAbstractor(){ }

protected:
CreationAbstractor(){ }
};

Typically, it would be used as argument to a class constructor like
this:

Driver::Driver( const CreationAbstractor<Car>& );

I attempted to make CreationAbstractor generic of up to N arguments:

template <class BaseT, class DerivedT = BaseT>
class Creator: public CreationAbstractor<BaseT>
{
private:
typedef boost::scoped_ptr<CreationAbstractor<BaseT> > ImplT;

ImplT impl_;

struct NoArgImpl: public CreationAbstractor<BaseT>
{ virtual BaseT* create() const{ return new DerivedT; } };

template <class F> struct Impl;

template <class A1>
struct Impl<void(A1)>: public CreationAbstractor<BaseT>
{
Impl( A1 a1 ): a1_( a1 ){}
virtual BaseT* create() const{ return new DerivedT( a1_ ); }
A1 a1_;
};

//etc...

public:

virtual BaseT* create() const
{
return impl_->create();
}

Creator(): impl_( new NoArgImpl ){ }
template <class A1>
Creator( A1 a ): impl_( new Impl<void(A1)>( a ) ){ }
//etc..
};

This seems to work fine, although I suppose you guys could
give me some pointers as to how to implement it better. The
problem that I have is that my original implementation had
only on type. Therefore:

template <class T>
class Creator: public CreationAbstractor<T>......(1)

This prohibit me from converting Creator<Derived> to
CreationAbstractor<Base>, despite my best efforts.

Does anybody know of a better implementation using nifty
conversions where a declaration as in (1) may suffice to do?

IOW:

const CreationAbstractor<Base>& a = const
CreationAbstractor<Derived>&...;compiles fine.

Regards,

Werner
 
W

werasm

werasm wrote:

Excuse my fast fingers. See below:
This seems to work fine, although I suppose you guys could
give me some pointers as to how to implement it better. The
problem that I have is that my original implementation had
only on type. Therefore:

only said:
template <class T>
class Creator: public CreationAbstractor<T>......(1)

This prohibit me from converting Creator<Derived> to
CreationAbstractor<Base>, despite my best efforts.

This prohibits..

Regards again,

W
 
W

werasm

werasm said:
Hi all,

I want to know whether the following is possible. I started out
with an idea called a CreationAbstractor. Basically just a
factory function wrapper for all types.

It looks like this:

template <class T>
class CreationAbstractor
{
public:
virtual T* create() const = 0;
virtual ~CreationAbstractor(){ }

protected:
CreationAbstractor(){ }
};

Typically, it would be used as argument to a class constructor like
this:

Driver::Driver( const CreationAbstractor<Car>& );

This seems to be a monologue. Anyway, yesterday after writing this
code I contemplated (after forgetting why) why I could not simply have
done

Driver::Driver( std::auto_ptr<Car> );

[Excuse my example... It is the only simple real world case I can
think of now.]

This would have solved the problem. Alternatively I could have used
something
like Loki Factories (I've read the chapter, yes). The reason the
auto_ptr would
not suffice, is that given the following:

Car( std::auto_ptr<Engine>, std::auto_ptr<Interior>...), the client
would be
inclined to try this:

Car( new ConcreteEngine(...), new LeatherInterior(...) );

Which is also frowned upon... not exception safe, so to speak. For
this reason the notion of a factory does not seem like a bad idea.

Loki factories (whilst I have great respect for the ideas) also have
its problems. The book gives to examples - OpNewFactoryUnit
that creates by calling new T(), and PrototypeFactoryUnit, that
uses Clone on prototypes. This implies either default or copy
constructors are required. This also does not cater for the
possibility of implementation classes being dependent on
other classes. There is another issue. Often creator objects
only need to live as long as required. Using prototypes
imply they live forever, and not using prototypes imply
default constructors are required. Another issue that I
contemplated is creating OpAbstractCreatorFactoryUnit. What
I don't like about this, is the fact that sometimes the creator may
have references to temporaries (like strings), and it may not live
longer than required (It ceases to live once the constructors scope
ceases). Storing these as variant to prototypes would imply they
would have to live indefinitely, meaning the creator may not contain
references to temporaries.

Therefore, back to the car example, this would make sense to
me:


Car( const CreationAbstractor<Engine>&, const
CreationAbstractor<Interior>&...)...

This does not burden the implementor with the need to copy construct.
The actual creation is delayed until the actual point of calling,
which would
be in the constructor initializer list - most likely, or in that of a
member, in
which case it would be forwarded. Also, its exception safe, as usually
the
concrete class is created on the stack.

Monologue complete, thank you.

Any implementation tips (or critique) would be welcome.

Kind regards,

Werner
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top