C++正本清源系列之二:你真的知道++i与i++的区别么?很简单的一个问题,但是你不一定答得对:
看下面的三行:Type i; // Line1
i++; // Line2
++i; // Line3其中Type是任意类型。问题:第二行与第三行有区别么?
不要告诉我一个在引用值之前自加另一个在引用之后自加,写在一个单独的行的时候,在这一点上是没有区别的。
但是,要是你说没有任何区别,那可就大错特错了。关键的问题在于:Type是什么?(在有了类的时代,这个可就不一样了)看我这样一个类:class Big
{
int _arBig[2048]; // ... Big& operator++()
{ // 前置++
return (*this);
} Big& operator++(int)
{ // 后置++
Big _Tmp = *this;
++*this;
return (_Tmp);
}
// ...
};呵呵,复制这样一个对象的成本是2048K内存的copy操作。
看这个函数:
Big& operator++(int)
{ // 后置++
Big _Tmp = *this;
++*this;
return (_Tmp);
}
哈哈,一个后置类型的++操作符竟然要复制一个对象,还要传出来它,就是说有至少一次2048K内存的copy操作(如果传出的值不被接收只是一次)
可是,不这样子做的话又要如何?大家可以看看B.S和S.L和S.M和H.S等人写的文章里面,凡是iterator类型的,全都是前置的++形式。其实,如果你不是很明白这一点,也没关系,咱们中国的程序员不光英语不是母语,还要受那些所谓的“教授”们写的书的毒害,惨到家了。(不过,inlined函数会使编译器的优化透过函数的界限,有可能将这个临时对象优化掉。但是,仅仅因为可能不会出大问题就要去做不应该做的事情么?更何况是一件举手之劳的事情,不,应该说是习惯的问题,养成良好的习惯是很重要的。而且,有一些问题是有必要深究的。许多人是在将C++Primer啃了一遍后,才知道自己过去不是真的懂得C++的)
下面是STL的红黑树的源代码:SGI STL
  _Self& operator++() { _M_increment(); return *this; }
  _Self operator++(int) {
    _Self __tmp = *this;
    _M_increment();
    return __tmp;
  }P.J.Plauger STLconst_iterator& operator++()
{ // preincrement
_Inc();
return (*this);
}const_iterator operator++(int)
{ // postincrement
const_iterator _Tmp = *this;
++*this;
return (_Tmp);
}
其余的STL版本类似

解决方案 »

  1.   

    int i;
    int j;
    int k;i=0;
    j= (i++) + (i++) + (i++) + (i++);
    i=0;
    k= (++i) + (++i) + (++i) + (++i);j=?
    k=?
      

  2.   

    sorry,上面写错了,因为是copy的代码,所以出了问题,第二个函数应该是: Big operator++(int)
    { // 后置++
    Big _Tmp = *this;
    ++*this;
    return (_Tmp);
    }也就是说,返回的不是引用类型。
      

  3.   

    楼上
    j = 0;
    k = 11;
    在VC6中的,想不通。望指教
      

  4.   

    It depends on different environment to test :)u can debug to watch the change
      

  5.   

    TO snsins你看清楚我是要讨论什么问题,这是“孔乙己问题”么?你在写一个 iterator的自加的时候,想过它的operator++的实现么?如果没有,请看一看,相信对你有好处的。可不要告诉我你没有用过iterator的自加 :)
      

  6.   

    int i;
    int j;
    int k;i=0;
    j= (i++) + (i++) + (i++) + (i++);
    i=0;
    k= (++i) + (++i) + (++i) + (++i);j=?
    k=?///////////////////j=i+i+i+i
    i++
    i++
    i++
    i++
    ///////////////////
    i++
    i++
    i++
    i++
    k=i+i+i+i
      

  7.   

    真得很有意思,比较如下两段代码: i = 0;
    k = (++i) + (++i);
    运行结束后,  i=2   k=4 i = 0;
    k = (++i);
             k += (++i);
    运行结束后,  i=2   k=3请高手指点
      

  8.   

    librastar2001(librastar) 的解释也不对,如果那样,第二种情况 k 应该等于10,实际计算结果为 11
      

  9.   

    现贴出反汇编的伪代码,针对第二种情况:i=0;
    k= (++i) + (++i) + (++i) + (++i);
    ///////////////////
    i=0;
    i++;i++;      // 关键在这儿,此句与下句颠倒一下,就是librastar2001的结果了 
    k = i;
    k = k + i;i++;
    k = k + i;i++;
    k = k + i;
      

  10.   

    zhangwei2001(东门吹雪) 
    请问怎么反汇编那?
      

  11.   

    printf("%d",i++)--------->i
    printf("%d",++i)--------->i+1