基本上,我的做法是:
我有一个抽象基类DataObject,它只提供类型信息(目前是double、int、bool),并由特定的数据容器继承,例如:
class DataObject
{
public:
virtual const Type *type() = 0;
};
template<class T, const Type * myType>
class DataObjectValue : public DataObject
{
T value;
public:
const Type *type(){return myType;}
};
但是,当我想执行加法运算时,我必须做类似于以下的操作:
DataObject * sum(DataObject *a, DataObject *b)
{
if(a->type() == &Integer and b->type == &Integer)
{
DataObjectValue<int>* ia = dynamic_cast< DataObjectValue<int>* >(a);
DataObjectValue<int>* ib = dynamic_cast< DataObjectValue<int>* >(b);
return new DataObjectValue<int>(ia->value+ib->value);
}
else if(a->type() == &Real and b->type == &Real)
{
DataObjectValue<double>* ra = dynamic_cast< DataObjectValue<double>* >(a);
DataObjectValue<double>* rb = dynamic_cast< DataObjectValue<double>* >(b);
return new DataObjectValue<double>(ra->value+rb->value);
}
else...
}
对于一些操作符(如 - * / < <= >= < > 等)和其他类型,重复的代码会很快让人感到烦恼。这样做很难维护。当然,我已经尽可能地简化了整个过程,引入了大量的模板,但是,我仍然认为可能有更清晰的方法。您是否 a) 理解我的问题(我怀疑我的解释,而不是您的能力)b) 有任何建议?
DataObjectValue
设为联合类型怎么样?这样,你就可以检查a.typy() == b.type()
然后使用switch
语句。虽然这并不会提高性能(也就是说,算法基本上是相同的),但你的代码会更加简洁。 - Shahbazswitch
语句可以转换为跳转表,但我认为一系列的if
/else if
语句不能。 - Seth Carnegie