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