MEC | 条款6 区别累加累减操作符的前置和后置形式

条款6:区别 increment/decrement 操作符的前置(prefix)和后置(postfix)形式

区分前置式和后置式

众所周知,重载函数是以其参数类型来区分彼此的。

然而不论 incrementdecrement 操作符的前置(prefix)和后置(postfix)形式,都没有参数。

为了填平这个漏洞,只好让后置式有1个int自变量,并且在它被调用时,编译器默默地为该 int指定0值:

class RandyInt {
public:
  RandyInt& operator++();         // 前置式(prefix)++ 
  const RandyInt operator++(int); // 后置式(postfix)++ 

  RandyInt& operator--();         // 前置式(prefix)-- 
  const RandyInt operator--(int); // 后置式(postfix)-- 

  RandyInt& operator+=(int);      // +=操作符,结合 RandyInt 和 ints
  ...
};

RandyInt i;
++i;  // 调用 i.operator++()
i++;  // 调用 i.operator++(0)

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

这里前置式返回一个引用(reference),increment 的前置式意义是“increment and fetch”(累加然后取出)

后置式返回一个const 对象,decrement 的后置式意义是"fetch and increment "(取出然后累加)

实现

class RandyInt {
public:
  RandyInt& operator++() {
    *this += 1;     // 累加(increment)
    return *this;   // 取出(fetch)
  };
  const RandyInt operator++(int) {
    RandyInt oldValue = *this; // 取出(fetch)
    ++(*this);                 // 累加(increment)
    return oldValue;           // 返回先前取出的值
  };

  RandyInt& operator--() {
    *this -= 1;
    return *this;
  };

  const RandyInt operator--(int) {
    RandyInt oldValue = *this;
    --(*this);
    return oldValue;
  };

  RandyInt& operator+=(int);
  RandyInt& operator-=(int);
};

后置式操作符并未调用其入参,该入参唯一的作用就是区别前置式和后置式。

当我们故意省略入参的名称时,编译器就不会对未使用的入参发出警告。

为什么后置式 increment 操作符必须返回1个对象(代表旧值),还是个 const 对象呢?

返回1个对象,因为该对象存储的是累加之前的旧值。

必须是个const 对象的原因是防止多重累加,看下面的代码:

RandyInt i;
i++++;        // wrong!实时后置式 increment 操作符2次
// 相当于下面的动作:
i.operator++(0).operator++(0);

operator++(0) 的第二个调用动作施行于第一个调用动作的返回对象,而该返回对象是个const,不允许2次累加

如果返回值不是const,则可以进行2次累加,但是第2次累加的作用对象是第1个operator++(0)返回的对象,而不是原对象,原对象只被累加了1次!这么做会在开发过程中与预期不符

但是++++i是允许的,改变的都是原对象。

效率比较

从实现能看出来, 后置式 increment 函数必须产生1个临时对象,用作返回值,该临时对象需要构造,也需要析构。

但从效率而言,前置式 不需要多创建1个对象,就能完成自身数值变化。

因此如果仅仅想改变某个RandyInt的值,使用 ++i 的效率比 i++ 高。

前置式和后置式保持行为一致性

无论前置式 increment 还是后置式 increment 操作符,它们都是将某个值累加。

因此为了确保后置式 increment 的行为与前置式 increment 行为一致,后置式 increment 和 decrement 操作符的实现应以其前置式兄弟为基础。

如此一来,只需要维护前置式版本就行了。


>>>>> 欢迎关注公众号【三戒纪元】 <<<<<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值