从抽象类向下转向右模板的最佳方法

时间:2015-02-18 15:33:37

标签: c++ polymorphism dynamic-cast

我最近有一个C ++任务,我遇到了一个关于多态的问题。

我们需要将值存储在模板化的类中,该类继承自抽象接口类。

enum eOperandType {
    Int8,
    Int16,
    Int32,
    Float,
    Double
};

class IOperand {
public:
    virtual eOperandType getType() const = 0; // Type of the instance
    virtual IOperand const *operator+(IOperand const &rhs) const = 0;
    virtual ~IOperand() {}
};

template<typename T>
class Operand : public IOperand {
public:
    Operand(T const &n, eOperandType type);    
    eOperandType getType() const;    
    IOperand const *operator+(IOperand const &rhs) const;

    T const value;
    eOperandType const type;
};

对于所有作业,我们被禁止编辑IOperand类,但可以自由使用我们需要的任何类。

稍后在代码执行时,数字被实例化,然后作为IOperand *存储在容器中。然后,我们获取此列表以操纵数字。

我的问题是找到如何将IOperand *转换为正确的操作数类型,以便操纵它并获得它的价值。

我尝试了一周的倍数方法,查看所有模板行为(当我尝试使用Operand<op.getType()>并且T为枚举时触及墙壁)

我的实际设计是使用了很多开关:

switch (op.value->getType()) {
    case Int8:
        if (dynamic_cast<Operand<int8_t>*>(op.value.get())->value != dynamic_cast<Operand<int8_t>*>(stack.front().get())->value) {
            throw RuntimeError("Assert failed. Whoopsie");
        }
        break;
    case Int16:
        if (dynamic_cast<Operand<int16_t>*>(op.value.get())->value != dynamic_cast<Operand<int16_t>*>(stack.front().get())->value) {
            throw RuntimeError("Assert failed. Whoopsie");
        }
        break;
    case Int32:
        if (dynamic_cast<Operand<int32_t>*>(op.value.get())->value != dynamic_cast<Operand<int32_t>*>(stack.front().get())->value) {
            throw RuntimeError("Assert failed. Whoopsie");
        }
        break;
    case Float:
        if (dynamic_cast<Operand<float>*>(op.value.get())->value != dynamic_cast<Operand<float>*>(stack.front().get())->value) {
            throw RuntimeError("Assert failed. Whoopsie");
        }
        break;
    case Double:
        if (dynamic_cast<Operand<double>*>(op.value.get())->value != dynamic_cast<Operand<double>*>(stack.front().get())->value) {
            throw RuntimeError("Assert failed. Whoopsie");
        }
        break;
    default:
        throw RuntimeError("wut");
        break;
}

解决我问题的最佳清洁解决方案是什么?我需要在倍数位置和函数中“向下”我的值以操纵值,这里的断言代码只是其中许多其他的例子。

我可以在这里使用C ++ 14,但不能使用任何外部库。

1 个答案:

答案 0 :(得分:0)

  当我尝试使用带有T的操作数时,

撞墙   枚举

模板在编译时进行评估。编译器为您使用的每种类型生成代码。像op.getType()这样的动态值需要编译器在编译之后创建代码,这在JIT编译语言中肯定是可能的,但在C ++中则不行。

我担心你的问题没有'漂亮'的解决方案。您确实需要一种如您所示的切换语句,并根据getType()的值来决定您的演员表。根据您的使用案例,虚拟功能可以帮助您,例如如果您想知道T

的字节大小
virtual size_t getSizeOf()
{
    return sizeof(T);
}

但由于您不允许修改IOperand,因此您仍然坚持使用您的解决方案。