一、容器的選擇
一般情況下,最容易想到也最常用的就是vector,但是如果要是頻繁在容器物件的中間刪除和插入元素,就要考慮使用list,因為list是基於節點的容器,當頻繁在容器中間刪除和插入元素時,不需要將很多元素整體向前或者向後移動,只需要操作節點元素指標指向的位置,效率較高且不會導致迭代器失效。如果頻繁在容器兩端刪除和插入元素,不僅可以使用vector,也可以使用deque.
如果對容器中的元素的順序有要求的話,可以考慮有序關聯內容器,如果對容器物件的查詢速度有要求的話,可以使用無序關聯容器
二、封裝容器的迭代器
封裝容器的迭代器的好處是當**中的容器從一種換到另一種時,不會修改大量的**
示例
void iter()
; vector::iterator it1 =find(v.begin(),v.end(), 3);
vector::iterator it2 = v.erase(++v.begin());
}
上面的**沒啥問題,但是當需要把vector換成list時,需要改動3.4.5行三處**
如果封裝容器的迭代器,則不用那麼麻煩
using viter1=vector::iterator;//c++11新的型別別名用法
typedef vector::iterator viter2;
void ecapiter()
; viter1 it1 =find(v.begin(),v.end(), 3);
viter1 it2 = v.erase(++v.begin());
}
此時,如果需要將容器修改為list,則只需要修改第一行和第六行**,只需要修改兩處,可能感覺修改的地方也沒少多少,但是,如果當需要修改容器時,**量一多,需要修改的地方就會越來越多,所以,把容器的迭代器封裝起來吧
三、當把自定義類的物件拷貝到容器中時,請拷貝自定義類的物件的指標,
當把元素放入容器中時,會將元素的拷貝放入容器中,拷貝是stl的工作方式
示例
class test
}
上面的**會產生記憶體洩露,乙個不是那麼好的解決辦法就是在函式的退出的時候,對vector中的每個指標都進行delete,但是如果函式出現異常,很有可能直接退出而沒有delete,所以,這時候要使用智慧型指標管理記憶體
void rightdelete()
}
上面的**就不會產生記憶體洩露,首先建立乙個臨時的智慧型指標變數,然後將臨時變數的拷貝push_back到vector中,然後臨時變數被釋放,此時shared_ptr的共享者數量為1,當函式退出時,v中的智慧型指標被銷毀,共享者數量為0,指向的記憶體自動被釋放
八、 刪除演算法remove和成員方法erase
remove並不能真正的刪除元素
示例
void removeanderase()
可見,remove並不能真正的將元素從容器中刪除
所以,如果想真的把元素從容器中刪除,需要在remove後再呼叫erase
將remove的返回值傳給erase是一種習慣用法
list將remove單獨實現,和remove演算法不同的是,list的remove成員函式可以成功刪除元素
同樣,list單獨實現的unique和演算法unique也也remove一樣,演算法unique並不會真正的對元素去重,而僅僅是對重複元素進行覆蓋,具體見部落格
而list的unique會真正的刪除元素,見部落格
因為演算法remove並不會真正的刪除元素,所以對於儲存指向堆記憶體指標的容器來說,單獨呼叫remove不僅沒有刪除元素,而且還會產生記憶體洩露,解決辦法就是在remove後,呼叫erase並使用智慧型指標
九、使用reverse避免不必要的重新分配記憶體
對於vector和string來說,如果知道預先要新增多少元素,要使用reverse擴大容器的容量,避免重新分配記憶體,提高程式的效率
參考《effective stl》
C 標準庫高階2
十 把容器資料傳給舊的介面 1.vector傳入陣列型api void stlwitholdapi int ps,size t num if v.empty return 0 先判段容器是否為空,然後傳入容器首元素的位址和長度即可 2.string傳入字串api void stlwitholdapi...
C 標準庫高階6
二十 二 函式指標和函式呼叫運算子的效率 使用less的sort呼叫比使用inline comp的sort呼叫快 原因是因為函式內聯。less operator 函式物件的operator 函式是內聯的,operator 的函式體可以直接被編譯器使用,直接在呼叫處進行展開。所以,sort中不包含函式...
C標準庫的閱讀(1)
c標準庫的閱讀 1 assert.h 1,基本內容 assert.h 裡面提供了乙個巨集 assert exp 這個巨集指向另乙個巨集 ndebug 如果你在include標頭檔案之前,定義了這個巨集 那麼 assert exp 的定義就是 void 0 意思是什麼也不做,相當與關閉斷言的功能,如果...