STL vector的內部實現原理及基本用法

2021-10-06 10:17:52 字數 4330 閱讀 4156

本文基於stl vector源**,但是不考慮分配器allocator,迭代器iterator,異常處理try/catch等內容,同時對_ucopy()、 _umove()、 _ufill()函式也不會過度分析。

template

_ty,

class

_ax>

class

vector

: public _vector_val<_ty _ax>

;

簡單理解,就是vector是利用上述三個指標來表示的,基本示意圖如下:

兩個關鍵大小:

大小:size=_mylast - _myfirst;

容量:capacity=_myend - _myfirst;

分別對應於resize()、reserve()兩個函式。

size表示vector中已有元素的個數,容量表示vector最多可儲存的元素的個數;為了降低二次分配時的成本,vector實際配置的大小可能比客戶需求的更大一些,以備將來擴充,這就是容量的概念。即capacity>=size,當等於時,容器此時已滿,若再要加入新的元素時,就要重新進行記憶體分配,整個vector的資料都要移動到新記憶體。二次分配成本較高,在實際操作時,應盡量預留一定空間,避免二次分配。

1、構造

vector的建構函式主要有以下幾種:

vector() : _mybase()

explicit

vector(size_type _count) : _mybase()

vector(size_type _count, const _ty& _val) : _mybase()

vector(const _myt& _right) : _mybase(_right._alval)

vector優異效能的秘訣之一,就是配置比其所容納的元素所需更多的記憶體,一般在使用vector之前,就先預留足夠空間,以避免二次分配,這樣可以使vector的效能達到最佳。因此元素個數_count是個遠比元素值 _val重要的引數,因此當構造乙個vector時,首要引數一定是元素個數。

由上各建構函式可知,基本上所有建構函式都是基於_construct _n() 的

bool _buy(size_type _capacity)

return (true);

}void _construct_n(size_type _count, const _ty& _val)

這樣就完成了vector容器的構造了。

2、析構

vector的析構函式很簡單,就是先銷毀所有已存在的元素,然後釋放所有記憶體

void _tidy()

_myfirst = 0, _mylast = 0, _myend = 0;

}

vector的插入和刪除元素是通過push_ back () 、 pop_back()兩個介面來實現的,他們的內部實現也非常簡單

void push_back(const _ty& _val)

void pop_back()

}

1、reserve()操作

之前提到過reserve(count) 函式主要是預留count大小的空間,對應的是容器的容量,目的是保證(_myend - _myfirst)>=count。只有當空間不足時,才會操作,即重新分配一塊記憶體,將原有元素拷貝到新記憶體,並銷毀原有記憶體

void reserve(size_type _count)

_myend = _ptr + _count;

_mylast = _ptr + _size;

_myfirst = _ptr;}}

2、resize()操作

resize(count) 函式主要是用於改變size的,也就是改變vector的大小,最終改變的是(_mylast - _myfirst)的值,當size < count時,就插入元素,當size >count時,就擦除元素。

void resize(size_type _newsize, _ty _val)

3、_insert_n()操作

resize()操作和insert()操作都會利用到_insert_n()這個函式,這個函式非常重要,也比其他函式稍微複雜一點

雖然_insert_n(_where, _count, _val ) 函式比較長,但是操作都非常簡單,主要可以分為以下幾種情況:

else

if (_capacity < size() + _count)

這種情況下,資料從原始容器移動到新分配記憶體時是從前到後移動的

這種情況下不需要再次進行記憶體分配,且資料是從後往前操作的。首先是將where~last向後移動,為待插入資料預留count大小的空間,然後從_mylast處開始填充,然後將從where處開始填充剩餘元素

else

if ((size_type)(_mylast - _vec_iter_base(_where)) < _count)

4、erase()操作

iterator erase(const_iterator _first_arg,

const_iterator _last_arg)

return (_first);

}

主要操作就是將後半部分的有效元素向前拷貝,並將後面空間的無效元素析構,並更新_mylast變數

5、assign()操作

assign()操作最終都會呼叫到下面的函式,主要操作是首先擦除容器中已有的全部元素,在從頭開始插入count個val元素

void _assign_n(size_type _count, const _ty& _val)

五、基本使用

在經過上述對vector內部實現的分析後,再來理解相應介面就變得簡單得多。

vector對外介面主要可以分為:

ectorc

vector

c1(c2)

vector

c(n)

vector

c(n, elem)

vector

c(beg,end)

c.~ vector

()

c.push_back(elem)

c.pop_back()

c.insert(pos,elem)

c.insert(pos,n,elem)

c.insert(pos,beg,end)

c.erase(pos)

c.erase(beg,end)

c.clear()

c.assign(beg,end)

c.assign(n,elem)

c.capacity()

c.max_size()

c.resize(num)

c.reserve()

c.size()

c.begin()

c.end()

c.rbegin()

c.rend()

operator

c.at(idx)

c.front()

c.back()

本文基於stl vector源**,但是不考慮分配器allocator,迭代器iterator,異常處理try/catch等內容,同時對_ucopy()、 _umove()、 _ufill()函式也不會過度分析。

STL vector的內部實現原理及基本用法

本文基於stl vector源 但是不考慮分配器allocator,迭代器iterator,異常處理try catch等內容,同時對 ucopy umove ufill 函式也不會過度分析。一 vector的定義 template class vector public vector val ty,...

jquery ready方法實現原理 內部原理

今天閒來無事研究研究jquery.ready 的內部實現,看jq的原始碼一頭霧水,由於自己很菜了,於是翻了翻牛人的播客,講述詳細,收穫頗多。先普及一下jquery.ready 和window.onload,window.onload事件是在頁面所有的資源都載入完畢後觸發的.如果頁面上有大等資源響應緩...

ConcurrentHashMap實現原理

concurrenthashmap實現原理 在jdk1.7中 concurrenthashmap是通過segment陣列 hashentry陣列 單鏈表的結構進行儲存資料。segment陣列中存放的是hashentry陣列的首位址,hashentry中存放的是乙個單鏈表 首節點位址 put 我們通過...