C++ 重载后缀运算符是如何工作的?

C++ 重载后缀运算符是如何工作的?,c++,operator-overloading,postfix-operator,prefix-operator,C++,Operator Overloading,Postfix Operator,Prefix Operator,我有以下代码: class Array { public: int aaa; Array():aaa(1){} void print() { cout << aaa << endl; } Array& operator++() { aaa++; return *this; } A

我有以下代码:

class  Array
{  
   public: 
       int aaa;
       Array():aaa(1){}
      void print()
      {
          cout << aaa << endl;
      }

      Array& operator++()
      {
          aaa++;
          return *this;
      }
      Array operator++(int)
      {
          Array a(*this);
          aaa++;
          return a;
      }
};
输出正是我所期望的。 现在,我将重载后缀函数中的代码更改为:

Array operator++(int)
{
     Array a(*this);
     a.aaa++; // changed this
     return a;
}
我把测试代码称为:

Array ar;
(ar++).print(); // this prints 2
ar.print(); // this prints 1
为什么我会得到这样的结果

  • 后缀运算符返回一个对象,而不是引用,因为它必须返回当前对象的未更改版本;它必须在增量完成之前返回值。因此,必须分配一个新对象。如果您返回了一个引用,它将是对什么的引用

  • 在第二个示例中,您创建了一个新对象,递增并返回它,但没有更改运算符应用于的原始对象——这显然是错误的,因此给出了错误的结果

  • 后缀运算符返回一个对象,而不是引用,因为它必须返回当前对象的未更改版本;它必须在增量完成之前返回值。因此,必须分配一个新对象。如果您返回了一个引用,它将是对什么的引用

  • 在第二个示例中,您创建了一个新对象,递增并返回它,但没有更改运算符应用于的原始对象——这显然是错误的,因此给出了错误的结果


  • 虽然前缀和后缀操作符在直觉上似乎都会对调用它们的对象进行变异,但它们实际上具有不同的语义。前缀操作符获取对象,对其应用增量操作,并返回相同的对象。后缀操作符获取一个对象,复制它,将增量操作符应用于原始对象,并返回副本


    正是由于这个原因,您可能已经看到了各种各样的来源,在可能的情况下不鼓励使用后缀操作符——因为后缀副本创建了一个临时对象,所以它的效率可能低于前缀操作符。对于一个必须维护大量状态信息的对象,使用后缀操作符可能会很昂贵。

    虽然前缀和后缀操作符在直觉上似乎都会改变调用它们的对象,但它们实际上具有不同的语义含义。前缀操作符获取对象,对其应用增量操作,并返回相同的对象。后缀操作符获取一个对象,复制它,将增量操作符应用于原始对象,并返回副本


    正是由于这个原因,您可能已经看到了各种各样的来源,在可能的情况下不鼓励使用后缀操作符——因为后缀副本创建了一个临时对象,所以它的效率可能低于前缀操作符。对于必须维护大量状态信息的对象,使用后缀运算符可能会很昂贵。

    您不能(更准确地说,不应该)返回对局部变量的引用,这是后缀运算符中的内容。对于上一个测试,您只增加临时对象的
    a
    ,而不是实际对象的。您不能(更准确地说,不应该)返回对局部变量的引用,这是后缀运算符中的引用。在上一次测试中,您只增加临时对象的
    a
    ,而不是实际对象的.FFR,其中一个星号是斜体,2个星号是粗体。这太搞笑了,抱歉,伙计们。不知道是什么让我开始输入BBCode!好的,我明白你的话了。但我尝试将数组运算符++(int)更改为void运算符++(int),它实际上工作正常。为什么呢?你能详细解释一下吗?@ipkiss——如果返回类型是
    void
    ,那么你不能将结果分配给任何东西——我几乎不能称之为“正常工作”!如果你不能分配结果,那么就不可能从前缀1.FFR中分辨出后缀增量操作符,一个星号围绕着某个东西是斜体,2是粗体。这太搞笑了,抱歉,伙计们。不知道是什么让我开始输入BBCode!好的,我明白你的话了。但我尝试将数组运算符++(int)更改为void运算符++(int),它实际上工作正常。为什么呢?你能详细解释一下吗?@ipkiss——如果返回类型是
    void
    ,那么你不能将结果分配给任何东西——我几乎不能称之为“正常工作”!如果无法分配结果,则无法区分后缀递增运算符和前缀递增运算符。您有一个小错误:后缀运算符将修改应用于原始。您有一个小错误:后缀运算符将修改应用于原始。
    Array ar;
    (ar++).print(); // this prints 2
    ar.print(); // this prints 1