• Advertisement
Sign in to follow this  

Creating an instance of a derived class ... only WHICH class??

This topic is 4838 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, Assume you got a class Factory that is designed for maximum genericity. It operates on instances of classes that are all derived from one common base class Super. In one of the methods of said class Factory, you need to create a new instance of the __same__ class that the operand belongs to. The problem is you do not know which class it belongs to because all you have is a reference of type Super. Now what?? =( What I've done to "solve" this problem is that I've defined a virtual method spawn() in the common base class Super that returns an instance of the respective class. But this means that every class directly or indirectly derived from Super needs to reimplement this method and do
Super& spawn() const
{
    return *( new _insert_name_of_class_here );
}

which .... sucks IMO. Can anyone think of a cleaner way to work around this? Thanks in advance for any helpful replies. Regards, ant

Share this post


Link to post
Share on other sites
Advertisement
Would that be the only alternative? Because actually all my derived classes are templates, and only Super is not. This is because I've tried putting as much functionality in Super as possible to maximize code sharing between the templatized, derived classes. But the only way to accomplish the spawn-functionality witout doing it the way demonstrated in my previous post would be to make Super a template as well, right?
Wait a second, what I'm talking about? You mean I should make my Factory class a template, right? Hmmm ...

Share this post


Link to post
Share on other sites
Quote:
Original post by Red Ant
What I've done to "solve" this problem is that I've defined a virtual method spawn() in the common base class Super that returns an instance of the respective class. But this means that every class directly or indirectly derived from Super needs to reimplement this method and do


So you actually need an instance to create one ?
At least my knowledge about factory classes are that they create the instances, not the instances themselves.

What about this solution:

template <typename T>
struct Spawn
{
T* spawn() { return new T(); }
};
class X : public super, public Spawn<X>
{...};


or this one:

class Factory
{
public:

template <typename T>
Super& spawn() const
{
return new T();
}

};


Sorry, I have no compiler at hand to check if those constructs are valid.

Just take them as a hint.

Share this post


Link to post
Share on other sites
Quote:
Original post by Red Ant
Would that be the only alternative?


I think I should explain my concerns about using templates in detail. You see, what I don't like about out-of-the-box templates is that, even though they're conceptually doing the exact same thing, they are in no way related to each other at runtime and you end up having multiple copies of very similar code in memory. This is why I normally derive my templates from a common (non-template) base class that implements any methods and data members that do not vary with changing T's (T as in template <class T>).

Share this post


Link to post
Share on other sites
Thanks for those ideas, nmi. Now I need some time to think them over. :)

Quote:
Original post by nmi
So you actually need an instance to create one ?
At least my knowledge about factory classes are that they create the instances, not the instances themselves.


Well, I only called it Factory because I couldn't think of a better name. My class isn't necessarily supposed to conceptually represent 'real' factories. To be honest, I don't really know what those factories you mentioned are.

Share this post


Link to post
Share on other sites
Something like
class factory{
.....
.....
.....
template<class T> T strange_wrapper_for_new(){
return new T;
};
template<class T> T another_strange_wrapper_for_new(T &i){
return new T;
};
.....
.....

sometype *a=somefactory.strange_wrapper_for_new<sometype>();
sometype *b=somefactory.another_strange_wrapper_for_new(a*);

or you can make entire factory to be templated. Say, make one non-template base class AbstractFactory that contains anything that doesn't depend to type of things produced by factory:

class AbstractFactory{
//place there code that doesn't depend to type of produced objects. Such as
virtual Super* spawn()=0;
// and other things
};

template <class T> SpecificFactory:public AbstractFactory{
// place there code that depends to T. Such as
T spawn_t(){return new T;}
virtual Super* spawn(){return spawn_t();}
};

Share this post


Link to post
Share on other sites
If you use templates right, you can reduce code size (e.g. by inlining, removed vtables) and increase speed (e.g. inlining, no indirection by vtable, better register allocation so fewer reads/writes).

Share this post


Link to post
Share on other sites
If you have the cash, buy Modern C++ Design which describes the development of both a factory and an abstract factory. Or borrow it from your public library. Or use the 14 day free trial here.

And download the code from Loki.

The factory can be configured to use clone, or prototypes etc.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement