1️⃣问题的引入

  • 重载函数是以参数类型来区分彼此,然而不论 ++或 – 操作符的前置或后置式,都没有参数。

  • 为了填平语言上的漏洞,只好让后置式有一个int自变量,并且在它被调用时,编译器默默为该int指定一个0值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class UPInt {					 		// "unlimited precision int"
    public:
    UPInt& operator++(); //前置式(prefix)++。
    const UPInt operator++(int); //后置式(postfix)++。
    UPInt& operator--(); // 前置式(prefix)-—。
    const UPInt operator--(int); //后置式(postfix)--。
    UPInt& operator+=(int); //+=操作符,结合UPInts和intS。
    ...
    };

    UPInt i;
    ++i; // 调用i.operator++();
    i++; // 调用i.operator++(0);
    --i; //调用i.operator--();
    i-- // 调用i.operator--(0);

2️⃣前置式和后置式的区别

  • 前置式返回一个引用reference,后置式放回一个 const 对象。

  • ++ 操作符的前置式意义increment and fetch(累加然后取出),后置式意义fetch and incremet(取出然后累加)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //前置式:累加然后取出(incrementandfetch)。
    UPInt& UPInt::operator++()
    {
    *this += 1; //累加(increment)。
    return *this; // 取出(fetch)。
    }

    //后置式:取出然后累加(fetchandincrement)。
    const UPInt UPInt::operator++(int)
    {
    UPInt oldValue = *this; //取出(fetch)。
    ++(*this); //累加(increment)。
    return oldValue; //返回先前被取出的值。
    }
  • 后置式会产生临时对象,作为返回值,效率低于前置式。

3️⃣进一步理解

  1. 为什么后置式++操作符必须返回一个对象(代表旧值),原因很清楚。但为什么是个const对象呢?

    1
    2
    UPInt i;
    i++++; //实施“后置式increment操作符”两次。
  • operator++ 的第二个调用动作施行于第一个调用动作的返回对象身上。
  • 第二个operator++所改变的对象是第一个operator++返回的对象,而不是原对象。因此即使下式合法:i++++; i也只被累加一次而已。
  1. 如何确保前置式和后置式行为一致?

    原则:后置式++--操作符的实现应以其前置式兄弟为基础。如此一来你就只需维护前置式版本,因为后置式版本会自动调整为一致的行为。