1

我有一个界面IOperand

class IOperand
{
   public:
     virtual IOperand * operator+(const IOperand &rhs) const = 0;
     virtual std::string const & toString() const = 0;
}

和班级Operand

template <class T>
class Operand : public IOperand
{
   public:
     virtual IOperand * operator+(const IOperand &rhs) const;
     virtual std::string const & toString() const;
     T    value;
}

IOperand和成员函数operator+toString原型不能被修改。成员函数 operator+ 必须添加 2 中包含的 2 个值IOperand。我的问题是这个值可以是 int、char 或 float,但我不知道如何使用模板来做到这一点。我试过这个:

template <typename T>
IOperand *              Operand<T>::operator+(const IOperand &rhs) const
{
  Operand<T> *op = new Operand<T>;
  op->value = this->value + rhs.value;
  return op;
}

我的toString方法:

template <typename T>
std::string const &     Operand<T>::toString() const
{
  static std::string s;  // Provisional, just to avoid a warning for the moment
  std::ostringstream convert;
  convert << this->value;
  s = convert.str();
  return s;
}

但是编译器没有找到this->valuerhs.value因为它们不在IOperand.

编辑:作为评论中的建议,我在 and 中添加了该方法toString,我真的不知道它是否有帮助。OperandIoperand

4

3 回答 3

3

如果IOperand真的不可触碰,你将不得不诉诸dynamic_cast

template <typename T>
IOperand * Operand<T>::operator+(const IOperand &rhs) const
{
  if (const Operand<T> *arg = dynamic_cast<const Operand<T>*>(&rhs))
  {
    Operand<T> *op = new Operand<T>;
    op->value = this->value + arg->value;
    return op;
  }
  else
    return NULL;  // Or any other sensible "error occured"
}

dynamic_cast只有当rhs实际上是与被调用的实例相同的实例时,Operand<T>才会operator +成功。然后在if.

但是,让我声明这是一个可怕的设计。运算符应该被重载以尽可能地表现出内置运算符的行为(除非您以域语言样式使用它们)。使用+on std::strings 也不会产生指向动态分配的指针std::string

除了代码易读性之外,它如此错误的主要原因是它很容易泄漏内存 - 唯一合理的实现operator+将动态分配内存,并且由于它返回一个原始指针,它留给调用者来确保内存是没有泄露。坏的东西。

于 2014-02-27T12:30:07.787 回答
0

Welcome to the wonderful word of binary operators. What do you want to happen when you do this:

IOperand* foo = new Operand<Matrix<Complex>>;
IOperand* bar = new Operand<Polynomial<FiniteField<5>>>;
IOperand* baz = *foo + *bar;

?

There are basically two possible answers. You want a compilation error, or you want a runtime error. The latter is easily doable with a dynamic_cast, the former is easily doable by throwing away your design, taking a CS university course, then PhD, then creating your own theory of binary operations and inventing your own OO language.

Of course don't neglect mundane things like memory leaks while doing all that.

于 2014-02-27T14:19:26.047 回答
0

使用类型名 T 定义 IOperandas 模板类

添加应该工作T get_value()class IOperand

重载此函数操作数,以便您可以获取子类中定义的数据

于 2014-02-27T12:25:13.360 回答