|
最近遇到了一个比较有意思的代码: {& W" [% X9 {7 A int i = 0; i = i++; - t# i; {6 Y9 R- f$ \8 f //问如果打印i的值,结果是多少?( h' ~1 S! N' } M4 f+ p# y return 0;, c5 G/ V c8 P$ R0 `8 D9 g } 这个问题实际上涉及到了前置及后置操作符的内部实现问题。 下面我们通过模仿前置和后置操作符的实现方式,来加深对前置、后置操作符实现原理的理解: % i& H, K+ D; D, F% p5 y, ^5 q 首先,我们使用类MyInt来模拟整型: + g. t, M: e9 T class MyInt{# g1 t6 i/ u, M+ R- M0 V- ]2 i+ Kpublic: int value; //实际的value值 MyInt(int value){ //方便初始化:MyInt i = 0;% u* w/ y1 h: Z1 w. P+ k; l: n this->value = value;( X: n; r5 }9 }1 l1 L9 I \' w } 0 S- ~6 `. Q2 n/ y; O4 G8 x /**( R$ ~7 Z$ C3 p2 N# c * 重写前置式++运算符(++i时会自动调用本函数): X/ n L' b+ r/ V * @return 前置式运算会返回当前对象的引用4 `3 |" \. q/ ~3 [ */ MyInt& operator++(){# P x; m3 W; Q$ b% z5 w& Z *this += 1; //累加后取出 return *this;3 K6 k- h8 f. t0 ~& x1 X }. ~; j, L6 e5 I( N$ S/ {# k / {: X: f* ?) y/ O/ {7 w /** * 重写后置式++运算符(i++时会自动调用本函数): S( e$ Y+ ?+ i$ r/ Q * 注意:由于函数重载是以参数类型来区分的,而前置、后置运算又都没有参数。为了解决这个语言学上的漏洞,只好让后置式运算符有一个int类型的参数(调用时,编译器会默默地为这个int型参数指定0值)3 ]" C5 f0 y: ?6 N; s* G/ z) `" D * @return 返回一个const类型的对象9 D5 a4 H& A* Z9 |3 ` */6 t! {9 F. _' H! o$ T5 {- q const MyInt operator++(int){ MyInt oldValue = *this; //取出当前对象 ++(*this); //累加(调用上面的前置++的重载函数) return oldValue; //返回先前被取出的值8 d# g. {2 b! r5 U! b j }$ B4 l X" C! J2 f0 F $ q' r0 p }) W /**6 @' J- m! ~ a: U. D. T! m * 重载运算符+=,方便赋值操作:*this += 1; */* i3 r5 Y: d* j! f MyInt& operator+=(int value){ this->value = this->value + value; return *this; } - G2 u/ E, u5 L4 H% E3 |6 }9 b7 k% g //MyInt &operator--(); //前置式--的实现与上面类似 //MyInt UPInt operator--(); //后置式--的实现与上面类似 };% j Q& }* U) x9 n# B 有了上面的代码,我们再来看main函数里的调用: #include "MyInt.h"1 l3 Y+ w; D+ G4 O' R$ e int main()9 L; X% A" l2 j7 R$ b { MyInt i = 0; //调用带参构造7 O- }. ^) A' q: K. z: K! e8 A ++i; //调用 i.operator++() i的值为1# L. z* f4 z4 C$ r, D# f1 i i++; //调用 i.operator++(0) i的值为2 return 0; }4 P% G% H# c+ a 4 T/ @( Z4 g% w9 f 从上面的结果看,都是实现了值的自增1 9 b6 z, b& F- h0 m% q 回到开始的问题:(使用我们模拟实现的类) . O* c8 i' B$ P int main(){ MyInt i = 0; i = i++; //问如果打印i的值,结果是多少? return 0;/ P1 r& X, [( v1 \9 K } & w1 c: l6 o. g/ h) m; b, B 首先会调用i++,即 i.operator++(0),函数代码如下: 2 Y9 c: N7 Z! m' `2 z /**) \5 \5 I* b4 [* 重写后置式++运算符(i++时会自动调用本函数) * @return 返回一个const类型的对象 */% p9 j) ~# q! @) u' M6 O1 B. s const MyInt operator++(int){ MyInt oldValue = *this; //注意:oldValue是*this的副本,不是引用 ++(*this); //这里累加的是*this对象,而不是oldValue* Z( z# d: d% G6 W; l return oldValue; //返回的oldValue值并没有变化,仍然是初值 }. d& t' s+ o! v9 I; g+ w 3 g; ]7 a% d! M8 ~ 所以,i.operater++(0)执行后,表达式就成了:i = 0,即 { //1、i = i++;0 U8 t/ _3 L2 F* X //2、i.operator+=(i.operator++(0)); //3、i.operator+=(0) -> i += 0& C6 ?2 H( b- s //4、i = 0 } i = i++ 运行的结果就为0。 |
微信公众号
手机版