2

我在这里要做的是重载 % 运算符,以便它将分子乘以给定的数字。我在程序中的所有其他重载运算符都可以正常工作,但是这个给我带来了问题。为了隔离这个问题,我创建了一个单独的更小的程序,只有这个重载的运算符。

从 modu.h 文件(省略了一些希望不相关的部分):

class fraction {
      private:
         int numerator, denominator;
      public:
         fraction ();
         fraction (int n, int d);
         void print ();
         void operator% (int x);
};

// the constructors and print functions work fine for the other overloaded
// operators so I decided to omit them

void fraction::operator%(int x) {
  numerator = numerator * x;
}

当我像这样在 main.cpp 文件中使用它们时

fraction frct (2, 3); // declare a fraction with a value of 2/3
frct = frct % 3;

我收到这些错误

modu.cpp:9:17: error: no match for ‘operator=’ in ‘frct = frct.fraction::operator%(3)’
modu.cpp:9:17: note: candidate is:
In file included from modu.cpp:3:0:
modu.h:6:7: note: fraction& fraction::operator=(const fraction&)
modu.h:6:7: note:   no known conversion for argument 1 from ‘void’ to ‘const fraction&’

当我像“ frct = frct.%(3); ”一样使用它时,我得到了错误:

modu.cpp:9:15: error: expected unqualified-id before ‘%’ token

我已经检查了几次是否缺少分号和花括号,但一切似乎都应该井井有条,并且 operator% 函数看起来与我工作的重载运算符没有任何不同。

4

2 回答 2

3

您在重载的运算符函数中没有返回值。像这样做:

fraction & fraction::operator% (int x) {
    numerator = numerator * x;
    return *this;
}

此外,由于您实际上是在更改对象的值,因此使用不同的运算符可能会更容易混淆,例如%=?

编辑:查看您实际使用运算符的方式(将结果分配回对象),我认为如果它实际上不更改对象而是使用结果创建一个新实例会更好,如下所示:

fraction fraction::operator% (int x) const {
    fraction result(*this);
    result.numerator = numerator * x;
    return result;
}
于 2013-04-28T08:25:41.777 回答
2

*首先,除非你讨厌维护你的代码的人,否则你不应该调用乘法%。我将*在我的答案中使用。

重载算术运算符时,有两种形式需要考虑:

  • 赋值形式 ,a *= b修改左操作数。这或多或少是你的超载。
  • 正常形式 ,a = b * c它返回一个新值而不修改任一操作数。这就是您尝试使用超载的方式。

赋值形式一般是成员函数,按照约定返回对修改对象的引用;这允许您在复杂的表达式中使用它,例如a = (b *= c). 它看起来像:

fraction & fraction::operator*=(int x) {
  numerator = numerator * x;
  return *this;
}

一旦你明白了,实现标准形式的一种简单方法是复制一个参数并将赋值形式应用于它。这种方法的一个优点是它不需要是成员或朋友,只要operator*=是公开的:

fraction operator*(fraction f, int x) {
  return f *= x;
}
于 2013-04-28T10:44:41.207 回答