正在删除虚拟继承

Removing Virtual Inheritance

本文关键字:继承 虚拟 删除      更新时间:2023-10-16

我正在处理一个嵌入式项目,我正试图删除一个已实现+/-*的虚拟数字类。删除这个类节省了很多代码空间,所以我用以下函数替换了+,

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();
}

有没有一种不那么丑陋的方法来实现这一点?因为我必须使用相同的方案进行其他操作和比较?

#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()很贵,那么你可以为每个论点计算一次答案,即使它使用了两次。

分两步做怎么样?

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;
}

我建议重新考虑您的体系结构。使用这种方法您节省了多少成本,在性能方面又花费了多少成本?您的新方法似乎将所有内容都推到了一个float(您没有显示res的声明,我认为它是float res;

检查这个修复程序对(a+b)*c之类的东西做了什么,其中a、b和c都是整数。有了这个修复程序,您现在有了一个浮点乘以int,这在计算上比int乘以int要贵得多。

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

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