用C++編程的都知道,C++提供了一個很是強大的操做符重載機制,利用操做符重載,咱們能夠爲咱們自定義的類增長更多很是有用的功能。不過,C++也有限制,就是當咱們爲自定義的類重載操做符時,重載操做符的含義應該跟內置類型同樣,好比,你不能經過重載+號操做符來實現兩個數相乘的運算,實現須要是兩個數相加的運算。本篇,我重點介紹下重載前置++和後置++的區別(前置--跟後置--相似)。c++
咱們知道,寫for循環年的時候,能夠用下面這兩種方式: 編程
for(int i=0; i<10; i++) { //do something } for(int j=0; j<10; ++j) { //do something }
如上兩種方式,i++跟++j到底有什麼區別呢?函數
首先,這兩種方式都會使得i跟j自增1, 不一樣的地方在於其內部實現; i++的實現原理是現將i自增1,而後返回i的引用(咱們知道重載操做符也是能夠有返回值的);而++j的實現原理是:先定義一個j的副本,而後在將j自增1,最後返回以前定義個那個副本的值。this
一般,c++的內置類型都要求前綴式操做符返回被增量或被減量對象的引用;而要求後綴式操做符返回被增量活被減量對象作增或減操做以前的副本(這裏邊就存在內存拷貝)。spa
實際的調用過程看起來應該是這樣:code
for( int i=0; i<10; i.operator++(0) ) { //調用後置++ //do something } for( int i=0; i<10; i.operator++() ) { //調用前置++ //do something }
看到這裏,你可能 有個疑問,爲何調用後置++的以後,參數列表要傳一個0而前置++卻沒有傳呢?對象
這裏就牽扯出前置++跟後置++的另外一個差異。blog
前置++和後置++在定義的都是同樣,看起來應該是下邊這樣:內存
class A { private: int a; public: A& operator++() { //... } A operator++() { //... } }
這樣,咱們就沒法區分到底哪一個是哪一個了,也許你會說它們的返回值不是不同嗎? 咱們老早就知道,沒法經過不一樣的返回值來重載不一樣的函數版本。編譯器
這種狀況下,爲了作區分也是爲了解決這一問題,通常要求後綴式操做符接受一個額外的int型形參(不會使用它,僅作區分用),來區別二者的不一樣。
class A { private: int a; public: A& operator++() { //前置++ //... } A operator++(int) { //後置++ //... } }
這樣,編譯器將爲咱們提供0做爲這個後綴式版本的形參。(也能夠調用這個有參數的版本作前綴式操做,不過通常不該該這麼作),下邊是完整定義:
class A { private: int a; public: A& operator++() { //前置++ ++a; return *this; } A operator++(int) { //後置++ A a = *this; ++*this; returnn a; } }
如上,操做符的後綴式比前綴式複雜一些,在實現後綴式版本時,通常先保存對象作自增/減以前的副本,而後調用本身的前綴版原本實現自增操做,最後將先前年保留的副本
返回。這裏須要注意的是,後綴式版本中,返回值是還沒有自增的原值,但對象自己已經作了自增操做了。
( ps : --操做符的前綴式和後綴式類型)