6. 區別increment/decrement操作符的前置(prefix)和后置(postfix)形式


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個改善編程與設計的有效方法 中文版》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM