我有一个接口(interface) IOperand
:
class IOperand
{
public:
virtual IOperand * operator+(const IOperand &rhs) const = 0;
virtual std::string const & toString() const = 0;
}
和操作数
类:
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
原型(prototype)不能修改。
成员函数 operator+ 必须添加包含在 2 个 IOperand
中的 2 个值。我的问题是这个值可以是 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->value
和 rhs.value
因为它们不在 IOperand
中。
编辑:作为评论中的建议,我在 Operand
和 Ioperand
中添加了 toString
方法,我真的不知道它是否可以提供帮助。
最佳答案
如果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
中进行检查.
但是,让我声明这是可怕的设计。操作符应该被重载以尽可能地表现出内置的操作符(除非您以领域语言风格使用它们)。使用 +
在 std::string
s 不会导致指向动态分配的 std::string
的指针要么。
撇开代码易读性不谈,它之所以如此错误的主要原因是它很容易泄漏内存——这是此 operator+
的唯一明智的实现方式。将动态分配内存,并且由于它返回一个原始指针,因此由调用者来确保内存不泄漏。 坏东西。
关于C++ : template member addition function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22068309/