Do all运算符重载将运算符放在将调用重载的对象之后

Do all operator overloads put the operator after objects whose overload would be called?

本文关键字:运算符 重载 对象 之后 调用 all Do      更新时间:2023-10-16

我有一个关于一元运算符重载的问题。代码如下:

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对象,f1f2f3。我知道代码:

f3=f1+f2等于f3=f1.operator+(f2),即运算符前面的对象将调用运算符,后面的对象将作为参数传递,对吗?

那么,对于一元运算符-,代码是

f3=-f1

按照上面对运算符+的想法,我认为代码应该像f3=f1-,它等于f3=f1.operator-()。为什么实际代码是f3=-f1而不是f3=f1-?我认为运算符前面的对象应该调用它……我知道在数学中,它是f3=-f1,但编译器如何识别代码f3=-f1,实际上是f1调用运算符?它怎么知道在这种情况下,-是一元运算符?

非常感谢!

只有两个一元运算符首先引用对象。这是后缀++和后缀--

如何在重载中区分这些内容的语法有点奇怪。你添加了一个伪参数:

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
};

以下是它的一些历史。你想怎么做就怎么做。

除了它们的后缀形式之外,所有其他一元运算符都出现在对象引用之前。包括:

  • 一元减(-)
  • 一元加(+)
  • 1补(~)
  • 地址(&)
  • 指针取消引用(*)
  • 逻辑NOT(!或否)

如果这让你感到不舒服,因为你习惯于看到"方法"总是出现在"对象"之后。。。那太糟糕了。有些语言的语法是有规则的。。。例如,使用全前缀或全后缀表示法。但认知科学家和语言学家认为,有观点认为,人类的大脑是基于一种语言本能运作的,我认为,许多纯粹一致的语言都与我们的大脑"在头脑中"创造结构的愿望作斗争。

无论哪种方式,正如@dyp所说,所有这些运算符都来自C(除了将!写为not的能力,我是这样做的,因为它在标准中,很难错过)。如果你对前面有减号的整数求反,那会很奇怪。。。然后用负号否定一个复数类。