C++之运算符重载(前置++和后置++)
今天在閱讀《google c++ 編程風(fēng)格》的文檔的時(shí)候,5.10. 前置自增和自減:有一句話引起了我的注意:
對(duì)于迭代器和其他模板對(duì)象使用前綴形式 (++i) 的自增, 自減運(yùn)算符.,理由是 前置自增 (++i) 通常要比后置自增 (i++) 效率更高。于是我查了查前置++和后置++的區(qū)別。
注意:《more effective c++》條款8也專門敘述了問(wèn)題。后來(lái)我發(fā)現(xiàn),下面的文章基本就是它的翻版,哈哈
前置++和后置++的區(qū)別?
《C專家編程》中有如下描述(P276,人民郵電出版社):
?
++a表示取a的地址,增加它的內(nèi)容,然后把值放在寄存器中;
a++表示取a的地址,把它的值裝入寄存器,然后增加內(nèi)存中的a的值;
?
另外,網(wǎng)上找了篇文章,通過(guò)從運(yùn)算符重載的角度來(lái)探討他們的不同,如下:
?
假設(shè)有一個(gè)類Age,描述年齡。該類重載了前置++和后置++兩個(gè)操作符,以實(shí)現(xiàn)對(duì)年齡的自增。
從上述代碼,我們可以看出前置++和后置++,有3點(diǎn)不同:
返回值類型的區(qū)別
前置++的返回類型是Age&,后置++的返回類型const Age。這意味著,前置++返回的是左值,后置++返回的是右值。(關(guān)于左值和右值的討論很多,見(jiàn)本文下面)
左值和右值,決定了前置++和后置++的用法。
++的類型是const Age,自然不能對(duì)它進(jìn)行前置++、后置++、賦值等操作。
++a的類型是Age&,當(dāng)然可以對(duì)它進(jìn)行前置++、后置++、賦值等操作
?
a++的返回類型為什么要是const對(duì)象呢?
有兩個(gè)原因:
a++的返回類型如果改成非const對(duì)象,肯定能通過(guò)編譯,但是我們最好不要這樣做。
?
++a的返回類型為什么是引用呢?
這樣做的原因應(yīng)該就是:與內(nèi)置類型的行為保持一致。前置++返回的總是被自增的對(duì)象本身。因此,++(++a)的效果就是a被自增兩次。
?
形參的區(qū)別
前置++沒(méi)有形參,而后置++有一個(gè)int形參,但是該形參也沒(méi)有被用到。很奇怪,難道有什么特殊的用意?
其實(shí)也沒(méi)有特殊的用意,只是為了繞過(guò)語(yǔ)法的限制。
?
前置++與后置++的操作符重載函數(shù),函數(shù)原型必須不同。否則就違反了“重載函數(shù)必須擁有不同的函數(shù)原型”的語(yǔ)法規(guī)定。
雖然前置++與后置++的返回類型不同,但是返回類型不屬于函數(shù)原型。為了繞過(guò)語(yǔ)法限制,只好給后置++增加了一個(gè)int形參。
?
原因就是這么簡(jiǎn)單,真的沒(méi)其他特殊用意。其實(shí),給前置++增加形參也可以;增加一個(gè)double形參而不是int形參,也可以。只是,當(dāng)時(shí)就這么決定了。
?
代碼實(shí)現(xiàn)的區(qū)別
前置++的實(shí)現(xiàn)比較簡(jiǎn)單,自增之后,將*this返回即可。需要注意的是,一定要返回*this。
后置++的實(shí)現(xiàn)稍微麻煩一些。因?yàn)橐祷刈栽鲋暗膶?duì)象,所以先將對(duì)象拷貝一份,再進(jìn)行自增,最后返回那個(gè)拷貝。
?
在Age的代碼中,后置++利用了前置++來(lái)實(shí)現(xiàn)自增。這樣做是為了避免“自增的代碼”重復(fù)。
在本例中,自增的代碼很簡(jiǎn)單,就是一行++i,沒(méi)有必要這樣做。但是在其它自增邏輯復(fù)雜的例子中,這么做還是很有必要的。
?
效率的區(qū)別
如果不需要返回自增之前的值,那么前置++和后置++的計(jì)算效果都一樣。但是,我們?nèi)匀粦?yīng)該優(yōu)先使用前置++,尤其是對(duì)于用戶自定義類型的自增操作。
前置++的效率更高,理由是:后置++會(huì)生成臨時(shí)對(duì)象。
?
從Age的后置++的代碼實(shí)現(xiàn)也可以看出這一點(diǎn)。
很明顯,tmp是一個(gè)臨時(shí)對(duì)象,會(huì)造成一次構(gòu)造函數(shù)和一次析構(gòu)函數(shù)的額外開(kāi)銷。雖然,編譯器在某些情況下可以優(yōu)化掉這些開(kāi)銷。但是,我們最好不要依賴編譯器的行為。
所以,在非內(nèi)置類型的時(shí)候,盡量使用前置++,因?yàn)樾矢?#xff08;后置自增,效率低)
轉(zhuǎn)載于:https://www.cnblogs.com/cthon/p/9185263.html
總結(jié)
以上是生活随笔為你收集整理的C++之运算符重载(前置++和后置++)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: CentOS 6.5编译安装Nginx+
- 下一篇: Bash中的shopt选项