以前听一位有经验的程序员说,i++和++i本身是有区别的。但通常在写代码的时候,尽量,最好,避免这种差异。
即,人为地,消除一些歧义。
(i++):postfix increment。
(++i):prefix increment。
int i = 3;
int j = i++;
int k = ++i;
这三个的区别,所有的程序设计书上都写了。
但我在学C++的operator overloading的时候,却发现……
i++++; 不能这么写。
++++i; 却是合法的。
虽然,这么写,真的是闲得x疼。我个人100000%不推荐。
但是,里面的原因还是很神奇的。
假设这里有一个class,叫CCount,CCount里有个member data,是cnt(int型)。
如果是 as a member function,前置、后置分别这么定义。
//prefix increment and postfix increment as member function CCount& CCount::operator++() { cnt++; return *this; } CCount& CCount::operator++(int) { CCount tmp(*this); cnt++; return tmp; }需要注意的有几点。
1. 同样可以as friend function来实现。
2. 两个函数prototype唯一不同的地方就是,带不带参数。不带参数的,是前置,带一个int的,是后置。
参数的作用一般也就仅仅只是为了区别前置还是后置。一般没有别的意义。所以以后根本就不要去想这个输入参数是用来干嘛的了…
3. 两个函数返回的,都是CCount &。
但是,前置++,返回的是发动这个++的那个obj本身,
而,后置++,返回的不是发动这个++的那个obj本身,而是另一个obj2。
所以,(++c) 做完以后,c的cnt自加1,但这个表达式?表达式还是对应的c原来的地址。
而,(c++)做完以后,c的cnt自加1,但这个表达式(·)的值是自加1之前的。
但是,在函数结束时,返回的却不是发动++的这个c本身,而是另一个临时tmp,(c++)这个整体返回的现在似乎已经是一个常量了。
所以对返回值再进行++,并不能实现对c再自增1。
就像:3++是不能通过的一样,c++++是不能通过的。
但是,++++c是可以通过的。因为++c,其实return的是发动++这个动作的c本身,所以还可以连续++。等价于:++ (++c)。大概是这样。
当然,overloading还可以通过 friend function实现。
//prefix decrement and postfix decrement as friend functions CCount & operator--(CCount& x) { x.cnt--; return x; } CCount & operator--(CCount& x, int y) { CCount tmp(x); x.cnt--; return tmp; }之所以能写 ----d,原因和上面类似。第一次--,返回的是发动--的这个d本身(函数输入参数是x的引用拷贝、别名拷贝,返回的也是CCount & 引用)。
之所以不能写 d----,也一样,d--返回的并不是d这个东西了,而是另一个tmp,对于(d--)这个整体来说,似乎已经是一个“常数”了。
写到这里,我觉得我自己陷入了极大的困惑。
如有不对的地方,请各位看官批评指正!Thx!