基于继承的 C++ 强制转换

Posted

技术标签:

【中文标题】基于继承的 C++ 强制转换【英文标题】:C++ casting on the base of inheritance 【发布时间】:2015-05-18 09:00:33 【问题描述】:

我有一个名为 addV 的方法,它接受两个参数。

static auto addV(Value* lval, Value* rval)

Value 类型是一个父类,它有 IntegerValue、StringValue、FloatValue 等子类。 我永远不知道哪个孩子会被送到 addV。确定它然后添加它的最简单和最优雅的方法是什么?

例子:lval = IntegerValue(10), rval = StringValue("Bruce"), return = StringValue("1Bruce")

例子:lval = StringValue("Tom"), rval = IntegerValue(2), return = StringValue("Tom2")

例子:lval = IntegerValue(1), rval = FloatValue(3.0), return = FloatValue(4.0)

我有一个 previous post 来做这件事,但使用原始类型。

值类:

class Value 
protected:
    typedef enum
        UndefinedType, 
        IntegerType, 
        ObjectType, 
        FloatType, 
        StringType, 
        BooleanType, 
        Last
     DataType;

    public:
    virtual DataType returnType()
        return UndefinedType;
    ;
;

IntegerValue 类:

class IntegerValue: public Value
public:
    int32_t val;

    IntegerValue(int32_t val) : val(val)

    DataType returnType()
        return Value::IntegerType;
    ;
;

FloatValue 类:

class FloatValue: public Value
public:
    float val;

    FloatValue(float val) : val(val) 

    DataType returnType()
        return Value::FloatType;
    ;
;

StringValue 类:

class StringValue: public Value
public:
    string val;

    StringValue(string val) : val(val)

    DataType returnType()
        return Value::StringType;
    ;
;

【问题讨论】:

看起来你想要某种multiple dispatch。您如何执行此操作取决于您可以使用的类型信息。你的Value 类是否有某种标签,可以用来识别对象的运行时类型,例如。 像这样的多次调度有几种不同的策略。要考虑的权衡是查找时间(线性 vs 对数 vs 常数)和维护成本(您是否更有可能在未来添加新的类型或新的函数 i>)。 给定的例子几乎是我在不知道它有名字的情况下想出的。那么这将是唯一的方法之一吗? Value 有一个名为 returnType 的方法,它从枚举列表中返回类型。 如果你有一个returnType 函数,你可以打开它的结果,static_cast 指向正确类型的指针,然后分派给这些类型的专用函数。 我稍后会尝试使用它。我也想过尝试 enable_if (如果它在没有模板的情况下工作)。 【参考方案1】:

我会从以下内容开始:

enum ValueTypesEnum 
   IntValueE = 0,
   FloatValueE = 1,
   StringValueE = 2
;


class Value 
public:
   virtual Value *create() = 0;
   virtual ValueTypesEnum getType() = 0;
   Value *max(Value *other) 
      if (getType() > other->getType()) 
         return this;
       else 
         return other;
      
   
;


template <ValueTypesEnum MyType, class ValueT>
class ValueFactory:public Value 
public:
   ValueTypesEnum getType() 
      return MyType;
   
   Value *create() 
      return new ValueT();
   
;


class IntValue: public ValueFactory<IntValueE, IntValue> 
;

class FloatValue: public ValueFactory<FloatValueE, FloatValue> 
;

class StringValue: public ValueFactory<StringValueE, StringValue> 
;


Value *addV(Value *lval, Value *rval) 
   lval->max(rval)->create();
   // change to: return lval->max(rval)->create()->set(lval)->add(rval);

然后在新创建的值中添加设置元素的实现 通过在具体类中实现setadd 虚方法。

【讨论】:

这是对现有代码的重组,如果我没看错,您是在将枚举传递给类吗?加法类将只是少数将使用此结构的类之一。稍后我将不得不玩这个。 @AdrianZ。实际上,我正在尝试使您的具体值类实现独立于枚举值本身。它还建议,当给定两个值类型时,应该创建哪种类型的信息可以通过枚举值等级存储在枚举本身中。唯一没有在这里包含的是 setadd 值的实现,这实际上是使您的应用程序工作的本质。 好的,我想我开始明白你是如何做到的了。我会尽快给出结果。 如果我尝试像这样实例化类“Value* iv = new IntValue();”我收到一条错误消息“./Values.h:39:16: 错误:从 'IntValue' 到 'Value *' 没有可行的转换返回 ValueT();”我不知道该怎么做,创建方法是什么?如果我错了也请纠正我,但是这个设计在每个单值子类中都有一个 add 方法?虽然我只需要 1 个核心添加方法。 您需要将行 return ValueT(); 更改为 return new ValueT(); 我将在答案中进行编辑...

以上是关于基于继承的 C++ 强制转换的主要内容,如果未能解决你的问题,请参考以下文章

C++ 子类化、继承和强制转换

C++ 继承和强制转换

C语言的多态是不是是类似于用结构指针的强制转换来实现的,具体实现方式类似于Linux万能链表???

向上强制转换和向下强制转换

C++强制类型转换操作符 dynamic_cast

泛型和强制转换 - 不能将继承的类强制转换为基类