C++ 类型工厂

C++ 类型工厂,c++,design-patterns,C++,Design Patterns,为了创建算术计算器,我必须创建一个工厂,该工厂将在参数中接受字符串,并根据字符串返回不同类型的变量 例如: TypeFactory.make("int") return int i=0; TypeFactory.make("float") return float f=0; 我想到了许多不同类型的实现,但似乎都不起作用: 我可以创建一个类类型,它的子类Float和Int,这将由工厂返回,但是我如何才能以通用方式在类中获取值(比如Type.getVal(),它不存在,所以我不能在程序的其余部分使

为了创建算术计算器,我必须创建一个工厂,该工厂将在参数中接受字符串,并根据字符串返回不同类型的变量

例如:

TypeFactory.make("int") return int i=0;
TypeFactory.make("float") return float f=0;
我想到了许多不同类型的实现,但似乎都不起作用:

我可以创建一个类类型,它的子类Float和Int,这将由工厂返回,但是我如何才能以通用方式在类中获取值(比如Type.getVal(),它不存在,所以我不能在程序的其余部分使用它)

我希望我的问题是清楚的(我甚至都不清楚!)

有人知道吗? 谢谢

编辑:

当我意识到这个问题很难理解时,我将以更一般的方式解释我必须做什么

目标是从文件中计算算术表达式。 例如:

那是我的档案。
我的程序将根据这些表达式构造一棵树。为此,我使用复合模式和访问者模式。但我的问题是,我必须在之前区分每种类型,在访问者执行操作时告诉哪些变量属于哪种类型,并能够得到正确类型的结果。

我的理解是,您需要解析和计算类型化算术表达式

通常的策略(在编译器中使用)是构建一个抽象语法树,然后对该树求值。 你需要的模式是

基本上,您可以将程序/表达式表示为节点树。Node是一个抽象类,包含许多派生类型,代表每种类型的表达式。 访问者模式允许您为每种类型的节点调用正确的访问者,从而决定要执行的正确代码

struct Visitor
{
  void process(IntNode i) { int r = i.getInt(); ... }
  void process(FloatNode f) { float r = f.getFloat(); ... }
};

struct Node
{
    virtual void getProcessed(Visitor v);
};
struct IntNode : Node
{
    virtual void getProcessed(Visitor v) { v.process(*this); }
    int getInt() {...};
};

如果可能的类型列表有限,请尝试使用
boost::variant

假设您只支持
int
float
。然后,您的数据将存储为
boost::variant


要访问这些值,可以使用
apply\u visitor
。添加两个值需要双重分派,这很棘手,但可行。您对其中一个的访问者然后访问另一个参数,并根据这两种类型生成不同的结果。

看起来您只是在寻找
默认(…)
运算符。您知道模板吗?类型是否需要以字符串的形式给出?是的,我知道模板,但我认为这里不能使用它,因为类型必须定义为类的声明,而我们不能这样做。(但可能有另一种使用模板的方法,我看不到)。类型需要以字符串的形式给出,因为整个思路是从文件中读取它。创建一个类型超类(
classtype{};
)并使用
std::map
)这不是问题所在,我确实打算在创建“类型”后将其堆叠到映射中。我不能做的是其他一切@Iliya Kogan我在看default(),我不知道。你能解释一下这会有什么帮助吗?事实上你完全正确,我就是这么做的,我使用复合模式和访问者模式(这很好)。但问题是在此之前:我必须能够访问具有不同类型的节点,如float或int…您的抽象节点必须能够回答其动态类型是什么。一旦您拥有了类型和正确的访问者,就可以根据具体情况调用getFloatValue或getIntValue。您还可以简单地在节点中放置一个
boost::any value
,让正确的访问者执行
get(node.value)
将IntNode/FloatNode扩展为单个模板类template可能是值得的,然后您可以使用
作废流程(IntNode/FloatNode)
而不是
作废流程(TypeNode)
作废流程(TypeNode)
,这样可以更容易地添加其他类型并减少代码重复。
struct Visitor
{
  void process(IntNode i) { int r = i.getInt(); ... }
  void process(FloatNode f) { float r = f.getFloat(); ... }
};

struct Node
{
    virtual void getProcessed(Visitor v);
};
struct IntNode : Node
{
    virtual void getProcessed(Visitor v) { v.process(*this); }
    int getInt() {...};
};