C 標準庫高階1

2021-10-11 11:26:55 字數 2517 閱讀 7664

一、容器的選擇

一般情況下,最容易想到也最常用的就是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 意思是什麼也不做,相當與關閉斷言的功能,如果...