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

后端 未结 7 2118
予麋鹿
予麋鹿 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 09:55

    It sounds like you might be using subclasses for things that should be encoded as fields.

    Instead of coding the different behaviour in 100 classes, consider building a look-up table with rules/constants/function-pointers that allow you to implement the proper behaviour from one class.

    For example, instead of:

    class SmallRedSquare  : public Shape {...};
    class SmallBlueSquare : public Shape {...};
    class SmallBlueCircle : public Shape {...};
    class SmallRedCircle  : public Shape {...};
    class BigRedSquare    : public Shape {...};
    class BigBlueSquare   : public Shape {...};
    class BigBlueCircle   : public Shape {...};
    class BigRedCircle    : public Shape {...};
    

    try:

    struct ShapeInfo
    {
       std::string type;
       Size size;
       Color color;
       Form form;
    };
    
    class Shape
    {
    public:
        Shape(std::string type) : info_(lookupInfoTable(type)) {}
    
        void draw()
        {
            // Use info_ to draw shape properly.
        }
    
    private:
        ShapeInfo* lookupInfoTable(std::string type) {info_ = ...;}
    
        ShapeInfo* info_;
        static ShapeInfo infoTable_[];
    };
    
    const ShapeInfo Shape::infoTable_[] =
    {
        {"SmallRedSquare",  small,  red, &drawSquare},
        {"SmallBlueSquare", small, blue, &drawSquare},
        {"SmallRedCircle",  small,  red, &drawCircle},
        {"SmallBlueCircle", small, blue, &drawCircle},
        {"BigRedSquare",      big,  red, &drawSquare},
        {"BigBlueSquare",     big, blue, &drawSquare},
        {"BigBlueCircle",     big,  red, &drawCircle},
        {"BigRedCircle",      big, blue, &drawCircle}
    }
    
    int main()
    {
        Shape s1("SmallRedCircle");
        Shape s2("BigBlueSquare");
        s1.draw();
        s2.draw();
    }
    

    This idea might not be applicable to your problem, but I figure it couldn't hurt to present it anyway. :-)

    My idea is like the Replace Subclass with Fields refactoring, but I go a bit further.

提交回复
热议问题