自增(++)和自減(--)操作符為物件加1 或減1 操作提供了方便簡短的實現方式。它們有前置和後置兩種使用形式。到目前為止,我們已經使用過前自增操作,該操作使其運算元加1,操作結果是修改後的值。同理,前自減操作使其運算元減 1。這兩種操作符的後置形式同樣對其運算元加 1(或減 1),但操作後產生運算元原來的、未修改的值作為表示式的結果:
1int i = 0
, j;
2 j = ++i; //
j = 1, i = 1: prefix yields incremented value
3 j = i++; //
j = 1, i = 2: postfix yields unincremented value
因為前置操作返回加1 後的值,所以返回物件本身,這是左值。而後置操作返回的則是右值。
建議:只有在必要時才使用後置操作符
有使用 c 語言背景的讀者可能會覺得奇怪,為什麼要在程式中使用前自增操作。道理很簡單:因為前置操作需要做的工作更少,只需加 1 後返回加 1 後的結果即可。而後置操作符則必須先儲存運算元原來的值,以便返回未加 1 之前的值作為操作的結果。對於 int 型物件和指標,編譯器可優化掉這項額外工作。但是對於更多的複雜迭代器型別,這種額外工作可能會花費更大的代價。因此,養成使用前置操作這個好習慣,就不必操心效能差異的問題。
後置操作符返回未加 1 的值
當我們希望在單個復合表示式中使用變數的當前值,然後再加1 時,通常會使用後置的 ++ 和 -- 操作:
1 vector ivec; //empty vector
2int cnt = 10;3
//add elements 10...1 to ivec
4while (cnt > 0
)5 ivec.push_back(cnt--); //
int postfix decrement
這段程式使用了後置的 -- 操作實現 cnt 減 1。我們希望把 cnt 的值賦給vector 物件的下乙個元素,然後在下次迭代前 cnt 的值減 1。如果在迴圈中使用前置操作,則是用 cnt 減 1 後的值建立 ivec 的新元素,結果是將 9 至 0十個元素依次新增到 ivec 中。
在單個表示式中組合使用解引用和自增操作
下面的程式使用了一種非常通用的 c++ 程式設計模式輸出 ivec 的內容:
1 vector::iterator iter =ivec.begin();2//prints 10 9 8 ... 1
3while (iter !=ivec.end())
4 cout << *iter++ << endl; //
iterator postfix increment
如果程式設計師對 c++ 和 c 語言都不太熟悉,則常常會弄不清楚表示式 *iter++ 的含義。
由於後自增操作的優先順序高於解引用操作,因此 *iter++ 等效於*(iter++)。子表示式 iter++ 使 iter 加 1,然後返回 iter 原值的副本作為該表示式的結果。因此,解引用操作 * 的運算元是 iter 未加 1 前的副本。
這種用法的根據在於後自增操作返回其運算元原值(沒有加 1)的副本。如果返回的是加 1 後的值,則解引用該值將導致錯誤的結果:ivec 的第乙個元素沒有輸出,並企圖對乙個多餘的元素進行解引用。
建議:簡潔即是美
沒有 c 語言基礎的 c++ 新手,時常會因精簡的表示式而苦惱,特別是像 *iter++ 這類令人困惑的表示式。有經驗的 c++程式設計師非常重視簡練,他們更喜歡這麼寫:
1 cout << *iter++ << endl;
而不採用下面這種冗長的等效**:
1 cout << *iter <2 ++iter;
對於初學 c++ 的程式設計師來說,第二種形式更清晰,因為給迭代器加 1 和獲取輸出值這兩個操作是分開來實現的。但是更多的 c++ 程式設計師更習慣使用第一種形式。
要不斷地研究類似的**,最後達到一目了然的地步。大部分的 c++ 程式設計師更喜歡使用簡潔的表示式而非冗長的等效表示式。因此,c++ 程式設計師必須熟悉這種用法。而且,一旦熟悉了這類表示式,我們會發現使用起來更不容易出錯。
自增 和自減 操作符
自增操作符和自減操作符經常要在我們自定義的類型別中使用到,而使用時經常會出現問題。現把自己在學習的過程中的 拿出來看一下,也是c primer中的例子如下 ifndef check ptr define check ptr include using namespace std class chec...
自增和自減操作符
毫無疑問,自增 和自減 操作符為物件加1或減1操作提供了方便簡短的實現方式。程式設計中的宗旨 簡潔即美 它們有前置和後置兩種使用形式 int i 0,j j i j 1,i 1 prefix yields incremented value j i j 1,i 2 postfix yields un...
過載自增和自減操作符
對於 和 這兩個一元運算子,存在前置和後置的問題,在定義時必須有所區分。1 用成員函式的形式來進行過載 如果 為前增量運算子時,過載函式的一般格式為 type classname operator 如果 為後增量運算子時,過載函式的一般格式為 type classname operator int ...