我有一个关于一元运算符重载的问题。代码如下:
class Fraction {
public:
Fraction() {}
Fraction(int a);
Fraction(int n, int d, int reduce=1);
Fraction operator +(const Fraction& y) const;
Fraction operator -(const Fraction& y) const;
Fraction operator -() const; // unary negation
// etc.
};
对于一元运算符-
,代码如下:
Fraction Fraction::operator -() const { return (Fraction(-num, denom, 0)); }
我们有三个Fraction
个对象,f1
,f2
和f3
。
我知道代码:
f3=f1+f2
等于f3=f1.operator+(f2)
,即操作符前面的对象将调用操作符,后面的对象将作为参数传递,对吧?
然后,对于一元运算符-
,代码是
f3=-f1
按照上面针对运营商+
的想法,我认为代码应该像f3=f1-
,等于f3=f1.operator-()
。为什么实际代码是f3=-f1
而不是f3=f1-
?我认为运算符前面的对象应该调用它...我在数学中知道它是f3=-f1
,但编译器如何识别实际上f3=-f1
的代码f1
打电话给运营商?它是如何知道在这种情况下,-
是一元运算符?
非常感谢!
答案 0 :(得分:1)
只有两个一元运算符首先引用对象。那个后缀++
和后缀--
。
如何在重载中区分这些语法有点奇怪。你添加一个假参数:
class Ptr_to_X {
// ...
X operator++(); //prefix: no argument
X& operator++(int); //postfix: because of
//the argument
X operator--(); //prefix: no argument
X& operator--(int); //postfix: because of
//the argument
};
Here's some history of how that came to be.按照你的意愿做好准备。
除了后缀形式之外,所有其他一元运算符都出现在对象引用之前。这包括:
如果它让你感到不舒服,因为你习惯于看到"方法"总是出现"在对象之后" ......那太糟糕了。例如,某些语言具有规范和常规的语法...使用所有前缀或所有后缀表示法。但认知科学家和语言学家认为,有人认为人类的思维运作是language instinct的论点,而且我认为许多纯粹一致的语言与我们的思想作斗争的愿望是创造了结构"在我们的头脑中"。
无论哪种方式,正如@dyp所说的那样,所有这些运算符都来自C(除了能够将!
写为not
,我这样做,因为它在标准中并且是很难错过)。如果你在前面否定带有减号的整数,那就太奇怪了......然后用一个带有减号的复数数字否定了它。