如何重载postfix运算符?

时间:2012-05-04 04:52:55

标签: 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;
      }
      Array operator++(int)
      {
          Array a(*this);
          aaa++;
          return a;
      }
};

我有一些问题如下:

  1. 为什么prefix返回一个引用,postfix返回一个对象?在C ++ Primer一书中,作者只解释了“For consistency with the built-in operators”。

  2. 然后,我测试了代码:

    数组ar;

        (ar++).print(); // print 1
    
        ar.print(); // print 2
    
  3. 输出正是我的预期。 现在我将重载后缀函数中的代码更改为:

    Array operator++(int)
    {
         Array a(*this);
         a.aaa++; // changed this
         return a;
    }
    

    我打电话给测试代码:

    Array ar;
    (ar++).print(); // this prints 2
    ar.print(); // this prints 1
    

    为什么我得到这样的结果?

2 个答案:

答案 0 :(得分:3)

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

  2. 在你的第二个例子中,你正在创建一个新对象,递增它并返回它,但是你没有改变运算符应用到的原始对象 - 这显然是错误的,所以给出了错误的结果。

答案 1 :(得分:0)

虽然前缀和后缀运算符在直观上似乎 mutate 调用它们的对象,但它们实际上具有不同的语义含义。前缀运算符接受一个对象,对其应用递增操作,并返回相同的对象。后缀运算符获取一个对象,复制它,将增量运算符应用于原点,然后返回副本。

正是由于这个原因,您可能已经看到各种消息来源阻止使用后缀运算符 - 因为后缀副本创建了一个临时对象,它可能效率低于前缀运算符。对于必须维护大量状态信息的对象,使用后缀运算符可能很昂贵。