C++中允許++ 和-- 操作符的前置和后置兩種形式具有重載的能力。而重載是以參數類型來區分的,然而不論是++ 還是 -- 的前置或后置均沒有參數,為了區分這兩種不同的操作,只好讓后置式有一個int自變量,並且在它調用的時候,編譯器默認給該int指定一個0值。
下面的例子是使char型也能進行++ 和 -- 的運算:
class Char { public: Char(char); Char& operator++ (); //前置式++ const Char operator++ (int); //后置式++ Char& operator-- (); //前置式-- const Char operator-- (int); //后置式-- Char& operator+= (int); //+=操作符 //... } Char C = 'a'; ++C; //調用C.operator++(); C++; //調用C.operator++(int); --C; //調用C.operator--(); C--; //調用C.operator--(int);
注意上面前置式和后置式的返回值的不同,僅以++操作符進行闡述:
C語言中++的前置和后置的區別為:前置式先累加后取出(increment and fetch),后置式先取出后累加(fetch and increment)。我們進行重載時,盡量不改變原來的意義,看看兩種操作的實現:
Char& Char::operator ++() { (*this) += 1; //increment return *this; //fetch } const Char Char::operator ++ (int) { Char oldValue = *this; //fetch ++(*this); //increment return oldValue; }
由上序代碼就能很回答:
前置式為什么要返回對象的引用了,因為直接對原對象本身進行了累加並返回自身。
后置式為什么要返回一個const對象?首先返回值必須是一個對象,這是顯然的,因為要返回累加前的對象;其次為什么是const對象呢?如果不是const對象會出現什么情況:
其一,違反了后置++的運算語法規則:C語言中不允許兩次使用后置++操作符,即下面的操作是非法的:
int i;
i++++; //error! (但++++i是合法的)
如果我們返回不是const對象,意味着下面的操作編譯器不會報錯:
Char c;
c++++; //不會報錯,調用的動作如下
//c.operator++(0).operator++(0);
其二,運算結果不符合我們的預期:假設允許返回是非const對象,那么其運算結果和我們期望的並不相同:
如上面的代碼,第二次operator++ 改變的對象是第一個operator++ 返回的對象,而不是原對象。即經過c++++之后,c的值也只是加了一次而已。這違反了我們的直覺,也違背了我們的意圖,因此應該被禁止!
到這里,++操作符的前置和后置應該比較清楚了,而--操作符完全類似。
最后,如果仔細觀察前置式和后置式,它們除了返回值不同,完成的任務是相同的:將某值累加!如果我們只需要進行累加,很顯然使用前置式的效率要比后置式的高,原因有兩點:
- 后置式++調用了前置式++的操作;
- 后置式要生成一個臨時對象存儲原值,這中間有拷貝構造和析構的代價,而前置式卻沒有。
因此,應該盡可能使用前置式操作!
參考文獻: 《More Effective C++ 35個改善編程與設計的有效方法 中文版》