前几天,当我尝试使用类成员函数重载双参数运算符时遇到了麻烦。我试过参考,但没有改变。编译器说我无法编写一个成员函数,该函数接受与类本身相同类型的多个参数。那是为什么?
以下是代码:
class Fraction
{
public:
Fraction(int num=1, int den=1): numerator(num), denominator(den) {}
Fraction(const Fraction& r): numerator(r.numerator), denominator(r.denominator) {}
Fraction& operator=(const Fraction&);
Fraction& operator*(const Fraction&, const Fraction&);
private:
int numerator, denominator;
};
Fraction& Fraction::operator=(const Fraction& r)
{
numerator = r.numerator;
denominator = r.denominator;
return *this;
}
Fraction Fraction::operator*(const Fraction& x, const Fraction& y)
{
Fraction z(x.numerator*y.numerator, x.denominator*y.denominator);
return z;
}
以下是编译器的错误消息:
Fraction& Fraction::operator*(const Fraction&, const Fraction&)' must take either zero or one argument
答案 0 :(得分:5)
运算符采用固定数量的参数,例如operator +,因为加法运算符只需要2个参数。如果它是一个成员函数,则第一个(最左边)隐含为 this ,第二个作为参数传递。
调用运算符+的三个参数是什么样的?有人可能会认为它看起来像 3 + 4 + 5 ,但这相当于调用operator +(3,4)然后是operator +(7,5)。
有关运营商列表及其参数的数量,请查看维基百科:http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
有关详细信息,还有另一篇详尽详述的StackOverflow帖子:Operator overloading
答案 1 :(得分:1)
首先,您所观察到的问题与成员函数一般无关。成员函数通常可以采用任意数量的“相同类”类型的参数。在您的示例中,您可以声明
class Fraction
{
void foo(Fraction &f1, Fraction &f2, Fraction &f3, Fraction &f4) {}
...
};
没有任何问题。因此,不清楚为什么你决定将你的问题写成一般的成员函数。
其次,在您的代码中,您实际上是在尝试重载运算符这一简单事实。 C ++中的运算符语法对于大多数(但不是全部)运算符是固定的。这立即意味着那些语法固定的运算符将具有固定数量的参数。
在您的示例中,它是运算符*
。它可以是一元(一个参数)或二元(两个参数)。当您通过成员函数重载此运算符时,已经隐含了一个参数,因此您只能添加零个或一个其他参数(分别用于一元*
和二元*
)。另一方面,您正在尝试添加两个更多参数以及隐式参数。即您正在尝试定义三元运算符*
。这是不可能的。 C ++中没有三元*
运算符。这正是编译器告诉你的。