it 的必要性

2021-09-12 14:05:02 字數 2120 閱讀 4071

for (std::vector::iterator itlocal = m_vecsoftwareer.begin(); itlocal != m_vecsoftwareer.end(); )

else

it++;

}如上所示,c++98中map::erase並沒有返回值為iterator的原型函式。 

那麼問題來了it=map.erase(it),然後對it進行操作會發生什麼呢?會發生傳說中的「未定義的行為」!包括但不限於程式掛掉、機器宕機、地球**、宇宙毀滅等–原因是什麼呢?在執行map.erase(it)之後,it這個iterator已經失效了,考慮c語言中乙個失效釋放了的指標,再次引用它會導致什麼問題呢?

在迴圈中正確使用map::erase的方法是什麼呢?如下:

for(map::iterator it = mapint.begin(); it != mapint.end();)

else}1

2345

6789

1011

在網上找mapint.erase(it++)的說明,比較詳細的一種解釋為: 

該方法中利用了字尾++的特點,這個時候執行mapint.erase(it++);這條語句分為三個過程 

1、先把it的值賦值給乙個臨時變數做為傳遞給erase的引數變數

3、再呼叫erase函式,釋放掉第一步中儲存的要刪除的it的值的臨時變數所指的位置。 

然而個人感覺比較費解,意思是第一步先把it的值傳給了函式呼叫的形參,然後又回去執行i+1的操作嗎?這樣總感覺it++的執行被硬生生的切成了兩部分,只能硬記住這一結論。 

直到後來看了《stl原始碼剖析》中的++i和i++實現方式的區別,然後某一天,再看到《more effective c++》裡的說明,突然開竅了,mapint.erase(it++)的機理終於不再神秘。 

其實在mapint.erase(it++)中,it++確實是作為乙個完整的執行過程,it++的具體實現**其實類似以下:

// postfix form: fetch and increment

map::iterator operator++(int)//通過乙個多餘的int引數與prefix++區分12

3456

7上面**的最終返回的值其實是tmp,tmp儲存的是*this的舊值,this後來通過increment函式自增了,但是tmp的依然保持原值,最後將tmp返回賦值作為erase的引數,所以在mapint.erase(it++)中,其實it++是作為乙個整體執行完成了的,在傳值給erase函式之前,it其自身其實已經+1了,不過字尾++返回的卻是乙個未執行+1操作的舊值,所以後面erase函式依然刪除的是原it位置的值,同時該迭代器失效,然而之前it已經+1自增過了,所以不受其影響噢。 

關於上面**中呼叫的字首++**類似如下:

// prefix form: increment and fetch

map::iterator& operator++()12

3456

也正因為字尾++會比字首++的操作多乙個臨時變數,並且其是以傳值複製的方式返回給呼叫方,所以一般而言字尾++的效率會比字首++效率低一些。

值得一提的是,在最新的c++11標準中,已經新增了乙個map::erase函式執行後會返回下乙個元素的iterator,然而不知道啥時候c++11才能達到現在c++98的覆蓋程度,謹慎一點還是使用map.erase(it++)比較保險。 

c++11

(1) 

iterator  erase (const_iterator position);

(2) 

size_type erase (const key_type& k);

(3) 

iterator  erase (const_iterator first, const_iterator last);12

3456

7最後,有的小夥伴可能會問為啥字首++和字尾++的返回值乙個是迭代器引用,乙個卻是迭代器傳值?簡單來說,字首++返回的便是傳參進來的迭代器,自然可以返回迭代器本身的引用,然而字尾++返回的是乙個函式內部的臨時變數,在函式執行完後便析構了,必然不能傳引用。注意既然是通過傳值的方式返回,對其返回值的修改對於原it是沒有影響的,舉例來說(it++)++的結果其實it只自增了一次,第二次++只是對其(it++)的返回值執行了++,對原it沒有任何效果。

this的必要性

先看下面一段 lesson8 necessary of this class person show name public void showinfo class demo 8 1 this屬於乙個物件,代表的是物件,其實就是乙個物件的引用,只能在類定義的方法中使用。那麼它代表那個物件呢?答 哪個...

sh c的必要性

在linux使用 echo 並配合命令重定向是實現向檔案中寫入資訊的快捷方式。比如要向 test.asc 檔案中隨便寫入點內容,可以 echo 資訊 test.asc 或者 echo 資訊 test.asc 下面,如果將 test.asc 許可權設定為只有 root 使用者才有許可權進行寫操作 su...

sh c的必要性

在linux使用 echo 並配合命令重定向是實現向檔案中寫入資訊的快捷方式。比如要向 test.asc 檔案中隨便寫入點內容,可以 echo 資訊 test.asc echo 資訊 test.asc下面,如果將 test.asc 許可權設定為只有 root 使用者才有許可權進行寫操作 sudo c...