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

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

时间:2014.03.11

地点:基地二楼

----------------------------------------------------------------------------

一、简述

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

//前置式,累加后取出
UPInt& UPInt::operator++()
{
  *this+=1;      //累加
  return *this;  //取出
}
//后置式,取出后累加
const UPInt upInt::operator++(int)
{
  UPInt oldVlaue=*this;      //取出
  ++(*this);                 //累加
  return oldVlaue;
}

----------------------------------------------------------------------------

二、为什么

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

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

UPInt i;
i++++;  //执行后置调用两次
上述代码等效于

i.operator++(0).operator++(0);
operator++的第二次调用动作实行于第一次调用动作返回的对象上。这并不是我们想要的,因为:一、它和内建类型的行为不一致。设计类的至上原则就是看int类型行为如何并遵循。显然int类型是不支持连续两次使用后置式操作的。二、如果我们去掉const,使得上述行为合法,但显然第二个operator++所改变的对象时第一个operator++返回的对象,而并非原对象,原对象还是只被增加了一次,这会使得违背你看起来加两次的意愿,引起混淆,所以干脆禁用。加上const后第一次调用operator++返回一个const对象,而此时连续再次operator++时将在这个const上执行,依据定义显然是非法的。如果有时你困惑于函数返回const对象是否合理,那么这里便是一个很好的例子。
  
另外是关于效率问题,后置式函数会产生一个临时对象,作为返回值之用。比如上面的oldValue,需要构造和析构,而前置式不会出现这种情况。所以说前置式天生效率高。