Dynamically creating an instance of a class from a string containing the class name in C++

后端 未结 7 2095
予麋鹿
予麋鹿 2020-12-31 09:00

Lets say I have a base class with 100 children:

class Base { 
  virtual void feed();
  ...   
};
class Child1 : public Base {
  void feed();  //specific proc         


        
7条回答
  •  时光取名叫无心
    2020-12-31 10:04

    I asked a question entitled automatic registration of object creator function with a macro that has the following example program that runs:

    #include 
    #include 
    #include 
    
    struct Object{ virtual ~Object() {} }; // base type for all objects
    
    struct ObjectFactory {
      static Object* create(const std::string& id) { // creates an object from a string
        const Creators_t::const_iterator iter = static_creators().find(id);
        return iter == static_creators().end() ? 0 : (*iter->second)(); // if found, execute the creator function pointer
      }
    
     private:
      typedef Object* Creator_t(); // function pointer to create Object
      typedef std::map Creators_t; // map from id to creator
      static Creators_t& static_creators() { static Creators_t s_creators; return s_creators; } // static instance of map
      template struct Register {
        static Object* create() { return new T(); };
        static Creator_t* init_creator(const std::string& id) { return static_creators()[id] = create; }
        static Creator_t* creator;
      };
    };
    
    #define REGISTER_TYPE(T, STR) template<> ObjectFactory::Creator_t* ObjectFactory::Register::creator = ObjectFactory::Register::init_creator(STR)
    
    namespace A { struct DerivedA : public Object { DerivedA() { std::cout << "A::DerivedA constructor\n"; } }; }
    REGISTER_TYPE(A::DerivedA, "A");
    
    namespace B { struct DerivedB : public Object { DerivedB() { std::cout << "B::DerivedB constructor\n"; } }; }
    REGISTER_TYPE(B::DerivedB, "Bee");
    
    namespace C { struct DerivedC : public Object { DerivedC() { std::cout << "C::DerivedC constructor\n"; } }; }
    REGISTER_TYPE(C::DerivedC, "sea");
    
    namespace D { struct DerivedD : public Object { DerivedD() { std::cout << "D::DerivedD constructor\n"; } }; }
    REGISTER_TYPE(D::DerivedD, "DEE");
    
    int main(void)
    {
      delete ObjectFactory::create("A");
      delete ObjectFactory::create("Bee");
      delete ObjectFactory::create("sea");
      delete ObjectFactory::create("DEE");
      return 0;
    }
    

    compile and run output is:

    > g++ example2.cpp && ./a.out
    A::DerivedA constructor
    B::DerivedB constructor
    C::DerivedC constructor
    D::DerivedD constructor
    

提交回复
热议问题