C++中自增和增减运算符的前置形式和后置形式

一、简述

  正如我们所见的,++和 — 都存在前置和后置两种形式,我们的记忆里的规则是:前置累加后取出,后置是取出后累加。我们来看定义,看它为什么会存在这种区别。

[cpp]

  1. //前置式,累加后取出  
  2. UPInt& UPInt::operator++()  
  3. {  
  4.   *this+=1;      //累加  
  5.   return *this;  //取出  
  6. }  
[cpp

  1. //后置式,取出后累加  
  2. const UPInt upInt::operator++(int)  
  3. {  
  4.   UPInt oldVlaue=*this;      //取出  
  5.   ++(*this);                 //累加  
  6.   return oldVlaue;  
  7. }  

—————————————————————————-

二、为什么

  为什么前置和后置在定义上会有区别,这种区别将导致什么样的结果,这是下面将要讨论的。

  首先看为什么后置式返回一个const对象?反证法:假如这样,那么下面程序是合法的:

[cpp]
  1. UPInt i;  
  2. i++++;  //执行后置调用两次  

上述代码等效于

[cpp]

  1. i.operator++(0).operator++(0);  

operator++的第二次调用动作实行于第一次调用动作返回的对象上。这并不是我们想要的,因为:一、它和内建类型的行为不一致。设计类的至上原则就是看int类型行为如何并遵循。显然int类型是不支持连续两次使用后置式操作的。二、如果我们去掉const,使得上述行为合法,但显然第二个operator++所改变的对象时第一个operator++返回的对象,而并非原对象,原对象还是只被增加了一次,这会使得违背你看起来加两次的意愿,引起混淆,所以干脆禁用。加上const后第一次调用operator++返回一个const对象,而此时连续再次operator++时将在这个const上执行,依据定义显然是非法的。如果有时你困惑于函数返回const对象是否合理,那么这里便是一个很好的例子。

另外是关于效率问题,后置式函数会产生一个临时对象,作为返回值之用。比如上面的oldValue,需要构造和析构,而前置式不会出现这种情况。所以说前置式天生效率高。

标签