   How to convert string to class?
  I have a string:"Car"I want to load this from a file and convert it into a Car object somehow. Actually, what i want is to access a static member function of "Car". Like so:file >> string;convert_string_to_class_somehow(string)::GetTotalCars();This is a simple example to illustrate what i'm trying to do. Is there any C++ mechanism for doing this? I'm trying to muck about with typeid's and whatnot, but i'm not finding a way to do it. I need to be able to address a class, but i won't know which class to address until i read the string from the file. It might be "Dog", "Cookie", or "McNugget". Who knows...Thanks again for your advice!   
  The way I have seen this done, though perhaps not the cleanest way, is simply to have a factory method that does something likeParrentClass * convert_string_to_class(const std::string& str){    if (str == "Car")   return new Car();    if (str == "Foo")   return new Foo();    return NULL;}[edited for code formating]   ;Quote:Original post by leiavoiaActually, what i want is to access a static member function of "Car".Given it is a static member function, the only way to call it is Car::GetTotalCars();. Factories only work out for virtual member functions.Quote:Is there any C++ mechanism for doing this? I'm trying to muck about with typeid's and whatnot, but i'm not finding a way to do it.That is because there is no way to do it, short of implementing all the nitty-gritty detail of the mapping yourself.   ;Quote:Quote:Is there any C++ mechanism for doing this? I'm trying to muck about with typeid's and whatnot, but i'm not finding a way to do it.That is because there is no way to do it, short of implementing all the nitty-gritty detail of the mapping yourself.Nuts. Maybe you can help with the contextual problem then:I have a resource manager. It loads modules (different resource for each module). Normally, i would need the modules to automatically load themselves via static member extratrickery (since statics are created by the compiler when the app starts). I'm trying to get around this. My thought was that i might be able to create a file with the names of the modules to load. Then the manager could do the actual module loading. But there isn't any good way to get the manager to map classes and/or function pointers to descriptive strings. If I could do that, i wouldn't need the file in the first place. This architectural issue has been bugging me for some time now. I've run into it several times and would really like to be able to find a way to solve it.;  Here's what I've got:#include <iostream>#include <map>#include <string>template<typename Base>class GenericFactory{public:  template<typename Type>  void register_class (const char *name)  {    map[name] = make_instance<Type>;  }  Base * make_instance (const char * string)  {    if (map[string]) return map[string]();    else return 0;  }private:  typedef Base* (*instance_maker) ();  std::map<std::string, instance_maker> map;  template<typename Type>  static Base * make_instance ()  {    return new Type;  }};class Foo{public:  virtual void sound_off () = 0;};class Bar: public Foo{public:  virtual void sound_off ()  {    std::cout << "Bar here" << std::endl;  }};class Baz: public Foo{public:  virtual void sound_off ()  {    std::cout << "Baz here" << std::endl;  }};int main (){  GenericFactory<Foo> f;  f.register_class<Bar>("Bar");  f.register_class<Baz>("Baz");  f.make_instance("Bar")->sound_off();  f.make_instance("Baz")->sound_off();}Now that I see you want to load your classes from an external module, this won't work as is. Constructors are not real functions so there's no sane way to load them dynamically. Your external module will need to contain a function which invokes the constructor.It's pretty easy to extend the above wrapper to cover this new requirement. Make the instance_maker typedef public and add the following function to the Generic Factory class:void register_class (const char *name, instance_maker proc){  map[name] = proc;}Then:int main (){  DynamicLoader dl("barbaz");  GenericFactory<Foo> f;  f.register_class("Bar", dl.get<GenericFactory<Foo>::instance_maker>("make_bar"));  f.register_class("Baz", dl.get<GenericFactory<Foo>::instance_maker>("make_baz"));  f.make_instance("Bar")->sound_off();  f.make_instance("Baz")->sound_off();};  I think i can make my generic pluggable factory work for me (somehow). I'll come back if i'm stumped again. Thanks for all your help.If you need it, here is the code for my pluggable factory with a sample for you. I was working on it some more just this evening, so i thought i might as well post it:PluggableFactory.h#ifndef PLUGGABLEFACTORY_H#define PLUGGABLEFACTORY_H#include <map>#include <string>#include <iostream>namespace LGC {// Pluggable Factory Template:template <class OBJECT> class PluggableFactory {public:virtual ~PluggableFactory() { }static OBJECT* GetNew( const std::string& s ) {FactoryMapIter i = registry->find(s);if ( i == registry->end() ) { return NULL; }OBJECT* obj = i->second->CreateNew();if (!obj) { return NULL; }return obj;}protected:// this should only be used by a static instance of the inherited classPluggableFactory( const std::string& s ) {// make secure from static initialization order problems of the registry (needed?):static bool inited __attribute__ ((unused)) = Init();registry->insert(  std::make_pair( s, this )  );}// the factory's personal create-object functionvirtual OBJECT* CreateNew()=0;private:typedef std::map< std::string, PluggableFactory<OBJECT>* > FactoryMap;typedef typename FactoryMap::iterator FactoryMapIter;static FactoryMap* registry;static bool Init() {registry = new FactoryMap();return true;}};template <class OBJECT> std::map<std::string,PluggableFactory<OBJECT>*>* PluggableFactory<OBJECT>::registry;/*MAKING IT WORK: ==========================================================// CREATE A FACTORY FOR EACH OBJECT TYPE YOU WANT TO MANUFACTURE:class CircleFactory : public PluggableFactory<Shape> {public:~CircleFactory() {}protected:CircleFactory() : PluggableFactory<Shape>("Circle") {}Shape* CreateNew() { return new Circle(); }static const CircleFactory auto_register_me;  };const CircleFactory CircleFactory::auto_register_me;// NOW USE IT:Shape* s = PluggableFactory<Shape>::GetNew("Circle");// FEEL FREE TO TYPEDEF IT TOO:typedef PluggableFactory<Shape> ShapeFactory;============================================================================*///// THIS IS THE 'ANOTATED' VERSION WITH DEBUGGING:////Pluggable Factory Template:// template <class OBJECT> class PluggableFactory {// public:// typedef std::map< std::string, PluggableFactory<OBJECT>* > FactoryMap;// typedef typename FactoryMap::iterator FactoryMapIter;// // virtual ~PluggableFactory() { }// // static OBJECT* GetNew( const std::string& s ) {// std::cout << "PluggableFactory::GetNew(): registry now contains [" << registry->size() << "] entries:" << std::endl;// FactoryMapIter i = registry->find(s);// if ( i == registry->end() ) { // std::cout << "PluggableFactory:: Can't find a Factory to make a " << s << std::endl;// return NULL;// }// OBJECT* obj = i->second->CreateNew();// if (!obj) { return NULL; }// return obj;// }// // protected:// // // this should only be used by a static instance of the inherited class// PluggableFactory( const std::string& s ) {// // make secure from static initialization order problems of the registry (needed?):// static bool inited __attribute__ ((unused)) = Init();// std::cout << "PluggableFactory:: Attempting to register a new factory: " << s << std::endl;// registry->insert(  std::make_pair( s, this )  );// std::cout << "PluggableFactory:: registry now contains [" << registry->size() << "] entries:" << std::endl;// // spit out all names// for ( FactoryMapIter i = registry->begin(); i != registry->end(); i++ ) {// std::cout << "" << i->first << std::endl;// }// }// // // the factory's personal create-object function// virtual OBJECT* CreateNew()=0;// // private:// // static FactoryMap* registry;// // static bool Init() {// registry = new FactoryMap();// return true;// }// };// // // template <class OBJECT> std::map<std::string,PluggableFactory<OBJECT>*>* PluggableFactory<OBJECT>::registry;} // end namespace LGC #endifpftest.cpp#include "PluggableFactory.h"#include <map>#include <string>#include <iostream>namespace LGC {class Shape {public:virtual void PrintName()=0;};class Circle: public Shape {public:void PrintName() { std::cout << "I AM A CIRCLE" << std::endl; }};class Square: public Shape {public:void PrintName() { std::cout << "I AM A SQUARE" << std::endl; }};class CircleFactory : public PluggableFactory<Shape> {public:~CircleFactory() {}protected:CircleFactory() : PluggableFactory<Shape>("Circle") {}Shape* CreateNew() { return new Circle(); }static const CircleFactory auto_register_me;  };const CircleFactory CircleFactory::auto_register_me;class SquareFactory : public PluggableFactory<Shape> {public:~SquareFactory() {}protected:SquareFactory() : PluggableFactory<Shape>("Square") {}Shape* CreateNew() { return new Square(); }static const SquareFactory auto_register_me;  };const SquareFactory SquareFactory::auto_register_me;}int main() {std::cout << "starting main. attempting to make a new circle..." << std::endl;LGC::Shape* c = LGC::PluggableFactory<LGC::Shape>::GetNew("Circle");if (!c) { std::cout << "No Circle!" << std::endl;}else {std::cout << "circle printing name..." << std::endl;c->PrintName();}std::cout << "attempting to make a new square..." << std::endl;LGC::Shape* s = LGC::PluggableFactory<LGC::Shape>::GetNew("Square");if (!s) { std::cout << "No Square!" << std::endl;}else {std::cout << "square printing name..." << std::endl;s->PrintName();}return 0;};  Since we're on the subject of factorys, I'll take a quick moment to shamelessly plug libindustry's factory class (requires boost, VS2k5 and GCC4.0.0 compatible), invented by myself :D.int main () {    industry::factory< Foo * , void ( void ) > f;    f.type< Bar >();    f.type< Baz >();    std::map< std::string , industry::type > ids;    ids[ "Bar" ] = typeid( Bar );    ids[ "Baz" ] = typeid( Baz );    std::auto_ptr< Foo > bar = f.create( ids[ "Bar" ] );    std::auto_ptr< Foo > baz = f.create( ids[ "Baz" ] );}Disclaimer: I'm leaning towards breaking compatibility in the next version (which will be released sometime after June 15th, when I move in and can reassemble my windows box) and requiring a key type.  The alternative is industry::keyed_factory, and/or making it a leading optional type which would involve making the internals even messier than they are.  This would only effect the decleration (the above would work with "industry::factory< industry::type , Foo * , void ( void ) > f;"), and allow the following as well:int main() {    industry::factory< std::string , Foo * , void ( void ) > f;    f.type< Bar >( "Bar" );    f.type< Baz >( "Baz" );    std::auto_ptr< Foo > bar = f.create( "Bar" );    std::auto_ptr< Foo > baz = f.create( "Baz" );}Removing "aspects" that currently allow:industry::factory< smart_ptr< Foo > , void ( void ) >(where smart_ptr = std::auto_ptr | boost::scoped_ptr | boost::shared_ptr)Is also under consideration - as the first post clearly demonstrates, it's un-needed to use smart pointers with industry::factory.  Since they also increase compile times and needlessly limit to a single ponter type, the arguments for it staying are limited.   