【问题标题】:C++ Object Creation through Inputs通过输入创建 C++ 对象
【发布时间】:2019-12-28 01:39:33
【问题描述】:

我想用输入的名字创建一个类的对象

class Rectangle {
public:
 int width;
 int height;
 ...
 //assume a constructor that assigns (width, height)
}

我将如何使用输入生成一个新名称的对象。 (不是我输入Rectangle myRectangle(1,1);

假设用户创建了从 1 到无限的对象

(我不是在寻求人工输入的帮助,也不是在检查他们是否仍然需要输入,只是如何使用输入来创建唯一命名的对象)

这是我的第一个堆栈溢出帖子,如果我做错了什么,请通知我。

干杯,

煤小子

【问题讨论】:

    标签: c++ class c++11 object visual-c++


    【解决方案1】:

    您可以使用从(用户提供的)类名到工厂函数的映射。

    class Creatable {
      virtual ~Creatable() {}
    };
    class Rectangle : public Creatable {
      int width;
      int height;
    };
    class Circle : public Creatable {
      int radius;
    };
    // assume suitable constructors for these
    
    // Given a string (with parameters such as the
    // radius or width/height) construct an object
    // and return a managed pointer to it
    using FactoryFunction_t =
        std::function<std::unique_ptr<Creatable>(std::string const &)>;
    
    // maps for example "rectangle" to a function which parses width and height from the string and returns an allocated rectangle
    std::map<std::string, FactoryFunction_t> factories;
    factories.insert({{"rectangle", CreateRectangle}, {"circle", CreateCircle}});
    
    factories.at("rectangle")("width=21; height=42;");
    

    如果可能的类在编译时已知,您也可以使用std::variant,而不是使用多态性(一个公共基类)。

    除了让每个工厂函数解析一个字符串之外,您还可以解析之前的参数 - 例如映射参数名称 -> 参数值并将其传递给工厂函数。

    如果您想让用户命名创建的对象,那么您可以将上面的托管指针保存在映射中:

    std::map<std::string, std::unique_ptr<Creatable>> objects;
    
    objects["my_rectangle"] = factories.at("rectangle")("width=21; height=42;");
    

    这可能是来自用户输入的结果,类似于:

    my_rectangle = 矩形(宽度=21;高度=42;);

    【讨论】:

    • 这确实是一个非常彻底的答案。请允许我补充一点,如果您想避免覆盖同名对象,if (!objects.insert({"my_rectangle", factories.at("rectangle")("width=21; height=42;")}).second) std::cerr &lt;&lt; "object already exists" &lt;&lt; std::endl; 可以轻松处理
    【解决方案2】:
    #include<vector>
    class Rectangle {
    public:
     int width;
     int height;
    };
    
    int main(){
    /*You can't use unique names. You can use a vector of objects
     std::vector<Rectangles> rectsVector; and then when you want
     to create anew object ask the user for (width,height) then
     rectVector.push_back(Rectangle{width,height}) and so on*/
    
        std::vector<Rectangle> rectsVector;
        size_t width{3},height{2};
        rectsVector.push_back(Rectangle{width,height});
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-30
      • 2018-11-04
      • 1970-01-01
      • 2012-03-25
      • 1970-01-01
      • 1970-01-01
      • 2010-09-11
      • 2016-03-18
      相关资源
      最近更新 更多