删除虚拟继承

时间:2011-06-02 15:59:41

标签: c++

我正在开发一个嵌入式项目,我正在尝试删除已实现+ / - *的虚拟数字类。删除此类可以节省大量代码空间,因此我已将+替换为以下函数,

if (BASE(h)->type() == FLOAT && BASE(v)->type() == FLOAT)
{
    res = FLOAT(h)->floatValue() + FLOAT(v)->floatValue();
}
else if (BASE(h)->type() == INTEGER && BASE(v)->type() == INTEGER)
{
    res = INTEGER(h)->intValue() + INTEGER(v)->intValue();
}
else if (BASE(h)->type() == INTEGER && BASE(v)->type() == FLOAT)
{
    res = INTEGER(h)->floatValue() + FLOAT(v)->floatValue();
}
else 
{
    res = FLOAT(h)->floatValue() + INTEGER(v)->floatValue();
}

有没有更简单的方法来实现这一目标?因为我必须对其他操作和比较使用相同的方案吗?

3 个答案:

答案 0 :(得分:2)

如何分两步完成?

isInt1 = BASE(h)->type()==INTEGER;
isInt2 = BASE(v)->type()==INTEGER;

if (isInt1 && isInt2)
  op1 = INTEGER(h)->intValue();
  op2 = INTEGER(h)->intValue();
  res = op1 + op2;
else {
  op1 = isInt1 ? (FLOAT(h)->floatValue()) : (INTEGER(h)->floatValue());
  op2 = isInt2 ? (FLOAT(v)->floatValue()) : (INTEGER(v)->floatValue());
  res = op1 + op2;
}

答案 1 :(得分:2)

#define GETFLOAT(arg) (BASE(arg)->type() == INTEGER ? INTEGER(arg)->floatValue() : FLOAT(arg)->floatValue())

switch(BASE(h)->type()) {
    case INTEGER:
        if (BASE(v)->type() == INTEGER) {
            res = INTEGER(h)->intValue() + INTEGER(v)->intValue();
            break;
        }
    case FLOAT:
        res = GETFLOAT(h) + GETFLOAT(v);
}

这实际上是h类型的两次分支,但只有在(你在其他地方的评论中说)的情况下,无论如何都是昂贵的,浮点运算。你可以用goto来避免这种情况,但我不会再有这个论点了。类似的东西:

switch(BASE(h)->type()) {
    case INTEGER:
        if (BASE(v)->type() == INTEGER) {
            res = INTEGER(h)->intValue() + INTEGER(v)->intValue();
            goto finished; // or better: return res;
        }
        hvalue = INTEGER(h)->floatValue()
        break;
    case FLOAT:
        hvalue = FLOAT(h)->floatValue();
}
res = hvalue + GETFLOAT(v);
finished:

与霍华德的答案一样,如果BASE()type()代价昂贵,那么即使它被使用了两次,你也可以计算每个参数的答案一次。

答案 2 :(得分:0)

我建议您重新考虑您的架构。你用这种方法节省了多少,而且性能成本是多少?您的新方法似乎将所有内容都推送到浮点数(您没有显示res的声明,我认为它是float res;

检查此修复程序对(a+b)*c之类的操作,其中a,b和c中的每一个都是整数。有了这个修复程序,你现在有一个浮点乘以一个int,这比一个int乘以int计算成本要高得多。

我建议使用模板并让C ++类型系统尽可能多地处理转换。这使您可以使用不必具有公共虚拟基类的不同存储类型。

您还可以通过仅实现int + float与float + int中的一个来减少程序大小(类似地使用int * float与float * int)。暂时实现int + float和float + int,但故意使一个引发编译时错误。翻转失败的操作数的顺序。