Object factory question

Started by
19 comments, last by stodge 21 years, 2 months ago
This is a tough question to phrase for me, so bear with me. Is there a way to have classes automatically register themselves with an object factory at runtime? For example, I need an object factory that I can do: ObjectFactory::CreateObject("MyObject"); which will return an object of type MyObject. I''ve read the Reflective Factory resource on this site(hope that''s the name), but I don''t understand it no matter how hard I try. Also, it doesn''t appear to do the above, unless I''m mistaken in which case please tell me! So how could I code what I need? I presume I need objects to call a static function inside the object factory at runtime using some funky-code. The factory would contain an STL map that maps class naames to instances of objects. If you understood that, then thanks. If you can help, thanks again!
---------------------http://www.stodge.net
Advertisement
I would do something like this:


  typedef Object * (*CreationFunction)();// The ObjectFactory class// This has to be implemented as a singleton for this to workclass ObjectFactory{    map < string, CreationFunction > ObjectMap;    static ObjectFactory & GetInstance()    {        static ObjectFactory factory;        return factory;    }    bool RegisterObject(string name, CreationFunction cf)    {        ObjectMap[name] = cf;        return true;    }    Object * CreateObject(string name)    {        CreationFunction cf = ObjectMap[name];        Object * obj = cf();         // not sure if this is syntax correct        // basically, call the function pointer that is stored        // in the map against the key "name"        return obj;    }};// Now each object is declared:// ShinyObject.hclass ShinyObject : public Object{    // some functions};// ShinyObject.cpp// You need to declare the creation functionObject * ShinyObjectCreationFunction(){     return new ShinyObject;}// You also define a functionbool RegisterShinyObject(){    return ObjectFactory::GetInstance().RegisterObject("ShinyObject", ShinyObjectCreationFunction);}// Now for the real magic :-)// Because its static const it will get automagically called *before* main startsstatic const bool ShinyObjectRegistered = RegisterShinyObject();  


Hope that helps,

Alan
"There will come a time when you believe everything is finished. That will be the beginning." -Louis L'Amour
Yes, there is a way. Search for "pluggable factory pattern"; the first link on google is a good one.

Don''t listen to me. I''ve had too much coffee.
You could also use the prototype pattern in conjunction with the factory pattern.

example:

    //all objects that are created should sub-class this. class MyObject {public:      virtual MyObject * clone() { return new MyObject(); }      virtual ~MyObject(){}};class Example: public MyObject {public:     virtual MyObject * clone() { return new Example(); }};  Then you simple register the prototype with the factory :      MyObject * protoype = new Example();ObjectFactory::GetInstance().RegisterObject("ShinyObject", protoype );//you can create instances like this:MyObject* ObjectFactory::create(string const & objName) {   map < string, MyObject* >::const_iterator it = objectMap.find(objName);  if(it != objectMap.end()) {      return (it->second)->clone();  }  else     return static_cast<MyObject*>(NULL);}    


[edited by - bslayerw on January 29, 2003 1:16:56 PM]
quote:Original post by stodge
This is a tough question to phrase for me, so bear with me. Is there a way to have classes automatically register themselves with an object factory at runtime?

No. There are all manner of hacks which allow you to pretend that you can do this, and none of them are actually "automatic registration". Of course, the word "hack" has an image problem, and has recently had a makeover to become "pattern". When you can''t do something in a language, you have to obscure the fact you can''t do it by spending hours writing oodles of code, by the end of which you''ve forgotten what you were actually trying to do, but had so much fun in the process that you''re going to make use of the end result anyway. The results of such activity have become known as "design patterns", and others have pointed you towards the particular pattern "pretend to automatically register a class, conveniently ignoring the bits that you have to write manually". Err... or is it called something else, I can''t quite remember...
quote:Original post by SabreMan
No. There are all manner of hacks which allow you to pretend that you can do this, and none of them are actually "automatic registration". Of course, the word "hack" has an image problem, and has recently had a makeover to become "pattern". When you can''t do something in a language, you have to obscure the fact you can''t do it by spending hours writing oodles of code, by the end of which you''ve forgotten what you were actually trying to do, but had so much fun in the process that you''re going to make use of the end result anyway. The results of such activity have become known as "design patterns", and others have pointed you towards the particular pattern "pretend to automatically register a class, conveniently ignoring the bits that you have to write manually". Err… or is it called something else, I can''t quite remember…


while i see your point i have to say that this argument can be applied to almost everything when you want.

The point isn''t that it

quote:
"pretend to automatically register a class, conveniently ignoring the bits that you have to write manually"<br> <hr height=1 noshade></SPAN></BLOCKQUOTE> <br><br>Yes, you do have to write your own creation/registration functions for each object, the point is that the ObjectFactory class has absolutly no knowledge of what objects are/are not available, so adding a new object just means creating its class, writing a creation/registration function and then starting to use it.<br><br><BLOCKQUOTE><SPAN CLASS=smallfont>quote:<hr HEIGHT=1 noshade><br>When you can''t do something in a language, you have to obscure the fact you can''t do it by spending hours writing oodles of code, by the end of which you''ve forgotten what you were actually trying to do, but had so much fun in the process that you''re going to make use of the end result anyway.<br> <hr height=1 noshade></SPAN></BLOCKQUOTE> <br><br>*Sigh*. If &#111;nly everything were as nice as lisp :-)<br><br>Alan
"There will come a time when you believe everything is finished. That will be the beginning." -Louis L'Amour
Thanks folks, some very interesting suggestions here.
---------------------http://www.stodge.net
SabreMan,

I don''t think you know what the hell you are talking about. How exactly do you consider design patterns a hack?? I would frankly be very scared to see a large scale project that you have worked one (if any).

Also, design patterns are not the be all end all solution to everything. They are simple a guideline and an easy way to communicate an idea if you know what design patterns are.

[qoute]When you can''t do something in a language, you have to obscure the fact you can''t do it by spending hours writing oodles of code

This is C++, you can pretty much do anything with the language! Writing oodles of code?? I''d rather write a strong framework up front than spend the rest of my life undoing what I had done if I did not have some sort of design to start of with (something that design patterns afford us).

the VTable is a beautiful thing. Learn to use it.
what about the object "registering" in the constructor?

There are several ways to handle it from there.
¤ If it''s the first one (the object checks himself) then it registers, this could be used with a class counter.
¤ It always registers but the factory checks to see if it''s already registered
etc...

did that help?

"No lies of sugar can sweeten the sournes of reality"

}+TITANIUM+{ A.K.A. DXnewbie[onMIRC]
[ ThumbView: Adds thumbnail support for DDS, PCX, TGA and 16 other imagetypes for Windows XP Explorer. ] [ Chocolate peanuts: Brazilian recipe for home made chocolate covered peanuts. Pure coding pleasure. ]

This topic is closed to new replies.

Advertisement