最近由於找工作需要,準備深入學習一下stl原始碼,我看的是侯捷所著的《stl原始碼剖析》。之所以看這本書主要是由於我過去曾經接觸過一些台灣人,我一直覺得台灣人非常不錯(這裡不涉及任何政治,僅限個人感受),在技術上他們比較嚴謹,在為人處世上也非常謙虛,所以一些台灣的技術資料我覺得是值得一看的。
想要學習stl原始碼的設計,其實應該是從空間介面卡(allocator)和迭代器(iterators)開始看起的,但是我沒有對這兩個部分做深入研究,主要原因是最近實在太忙,要寫**又要兼顧找工作,不能在這上面投入太大精力,而這兩個部分又不太容易看懂,所以我決定先從容器開始看起,這樣在編碼時用到c++標準庫的時候會更有底氣。
關於容器的設計,其實我們在演算法與資料結構課程裡都涉及過,但是當時主要集中於理解設計理念,沒有真正編過一套完整的庫去應用我們學習到的知識,所以讀者在學習c++標準庫的時候我覺得應該結合過去資料結構的知識,關注它實現的技巧和為什麼這麼實現,通過學習優秀**提公升自己的程式設計能力。
容器分為序列式容器與關聯式容器,本篇部落格主要討論序列式容器,所謂序列式容器,其中的元素都可序(ordered),但是未必有序(sorted)。c++本身提供了乙個序列式容器array,stl另外再提供vector、list、deque,再以此為基礎實現heap(內含vector),stack和queue(內含deque),後面會展開敘述,其實這裡的stack和queue只是將deque改頭換面而形成的,技術上被歸類為一種配接器(adapter)。
由於篇幅,本文還是從使用者的角度介紹各個介面的設計思路。
vector維護的是乙個連續線性的空間,所以它的迭代器很好實現,只需要乙個普通指標就可以(和元素型別無關),迭代器所需要的操作行為包括:operator*,operator->,operator++,operator--,operator+,operator-,operator+=,operator-=,普通指標天生就具備。,vector支援隨機訪問,它提供的是random access iterators,普通指標也有這樣的能力。所以,如果客戶端寫出這樣的**:
vector::iterator ivite;
那麼ivite的型別就是int *。
vector裡面有三個迭代器,start、finish、end_of_storage,分別指向當前連續空間所使用的頭和尾、整塊連續空間的尾。為了降低空間配置時的速度成本,vector實際配置的大小要比客戶端需求量更大一些,以備將來的使用。vector空間的增長實際上是乙個浩大的工程,開銷非常大,它需要申請一塊新的連續空間,然後把已有的內容拷貝過去,這裡面每次新擴充的空間都是原空間的兩倍大,這樣做可以把擴充空間的時間複雜度降低到o(n),如果每次新擴充的空間相比於原空間增加乙個固定的大小m,那麼無論m取何值,都可以證明最後的時間複雜度正比於n的平方。
void push_back(const t& x) //將元素插入於vector的尾端,該函式首先檢查是否還有備用空間,如果有就直接在備用空間上構造元素,調整迭代器finish,如果沒有備用空間,就
//擴充空間(重新配置、移動資料、釋放原空間)
void pop_back() //將尾端元素刪除。
iterator erase(iterator first,iterator last) //刪除[first,last)中的所有元素
iterator erase(iterator position) //清除某個位置上的元素
void clear() //清除所有元素
void insert(iterator postion,size_type n,const t& x) //從position開始,插入n個元素,元素初值為x
list和vector是兩個最常用的容器,list的特點是:每次插入或刪除乙個元素,就配置或釋放乙個元素空間。list對於空間的運用有絕對的精準,而且對於任意位置的元素插入或刪除的時間複雜度是o(1),但是list不支援隨機訪問,它只能從頭開始遍歷元素,這點不如vector,因此它們的使用需要根據具體的情況具體分析。
list不像vector一樣可以用普通指標作為迭代器,因為其結點不保證在儲存空間中連續存在。list迭代器需要能夠指向list的節點,並且可以進行正確的遞增、遞減、取值操作、成員取用操作,其實都很簡單,這裡不列**了。
《STL原始碼剖析》 序列式容器
stl原始碼剖析 前言 所謂的序列式容器,其中的元素都可序,但未必有序,c 本身提供了乙個序列式容器array,stl 提供了vector,list,deque,srack,queue,priority queue等 一.使用reverse 函式提前設定容量大小 1.1 提前設定的原因 對於vect...
STL原始碼剖析 序列式容器之deque
deque概述 deque是一種雙開口的連續線性空間,可以在頭尾兩端分別做元素的插入和刪除操作 deque沒有容量的概念,它是動態地以分段連續空間組合而成,隨時可以增加一段新的空間並鏈結起來 deque的中控器 deque由一段一段的定量連續空間構成 一旦有必要在deque前端或尾端增加新空間,便配...
stl原始碼剖析序列式容器之vector
首先介紹下容器的概念,容器是將一些運用最廣的資料結構實現出來,並且根據資料在容器中的排列特性,這些資料結構分為序列式容器以及關聯式容器兩種。其中序列式容器包括array c 自建 vector heap priority queue 由heap演變 list slist deque stack和qu...