欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

STL容器之vector源碼詳細解讀

 更新時間:2024年01月03日 08:56:38   作者:DivineH  
這篇文章主要介紹了STL容器之vector源碼詳細解讀,vector的數(shù)據(jù)安排和array和類似,它們的主要差別在于空間的運用和靈活性,array是靜態(tài)空間,一旦配置了就不能改變,需要的朋友可以參考下

簡介

vector的數(shù)據(jù)安排和array和類似,它們的主要差別在于空間的運用和靈活性,array是靜態(tài)空間,一旦配置了就不能改變

vector是動態(tài)空間,隨著元素的加入,它會自動擴充空間以容納新的元素。

構(gòu)造函數(shù)

// 默認構(gòu)造函數(shù)
explicit vector(const allocator_type& __a = allocator_type())
: _Base(__a) {}

// 構(gòu)造擁有 n 個有值 value 的元素的容器
vector(size_type __n, const _Tp& __value,
        const allocator_type& __a = allocator_type()) 
: _Base(__n, __a)
{ _M_finish = uninitialized_fill_n(_M_start, __n, __value); }

explicit vector(size_type __n)
: _Base(__n, allocator_type())
{ _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); }

// 拷貝構(gòu)造,構(gòu)造擁有 __x 內(nèi)容的容器
vector(const vector<_Tp, _Alloc>& __x) 
: _Base(__x.size(), __x.get_allocator())
{ _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); }

// 構(gòu)造擁有范圍 [first, last) 內(nèi)容的容器
template <class _InputIterator>
vector(_InputIterator __first, _InputIterator __last,
        const allocator_type& __a = allocator_type()) : _Base(__a) {
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_initialize_aux(__first, __last, _Integral());
}
// 構(gòu)造擁有范圍 [first, last) 內(nèi)容的容器
vector(const _Tp* __first, const _Tp* __last,
        const allocator_type& __a = allocator_type())
: _Base(__last - __first, __a) 
{ _M_finish = uninitialized_copy(__first, __last, _M_start);

主要函數(shù)

vector中主要有以下幾個內(nèi)部變量:

_Tp* _M_start;  // 表示目前使用空間的頭
_Tp* _M_finish; // 表示目前使用空間的尾
_Tp* _M_end_of_storage; // 表示目前可用空間的尾

其在內(nèi)存中的示意圖如下所示:

在這里插入圖片描述

我們下面主要看vector添加元素的push_back函數(shù)。

push_back

push_back的源代碼如下所示:

// 尾部插入
void push_back(const _Tp& __x) {
if (_M_finish != _M_end_of_storage) { // 有備用空間
    construct(_M_finish, __x);    // 全局函數(shù),將 __x 設(shè)定到 _M_finish 指針所指的空間上
    ++_M_finish;         // 調(diào)整
}
else
    _M_insert_aux(end(), __x);  // 無備用空間,重新分配再插入
}

template <class _Tp, class _Alloc>
void 
vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x)
{
  if (_M_finish != _M_end_of_storage) {   // 有備用空間
    construct(_M_finish, *(_M_finish - 1));
    ++_M_finish;
    _Tp __x_copy = __x;
    copy_backward(__position, _M_finish - 2, _M_finish - 1);
    *__position = __x_copy;
  }
  else {  // 沒有備用空間
    const size_type __old_size = size();
    const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
    iterator __new_start = _M_allocate(__len);
    iterator __new_finish = __new_start;
    __STL_TRY {
      __new_finish = uninitialized_copy(_M_start, __position, __new_start);
      construct(__new_finish, __x);
      ++__new_finish;
      __new_finish = uninitialized_copy(__position, _M_finish, __new_finish);
    }
    __STL_UNWIND((destroy(__new_start,__new_finish), 
                  _M_deallocate(__new_start,__len)));
    destroy(begin(), end());
    _M_deallocate(_M_start, _M_end_of_storage - _M_start);
    _M_start = __new_start;
    _M_finish = __new_finish;
    _M_end_of_storage = __new_start + __len;
  }
}

vector插入元素的主要步驟為:

1、判斷備用空間是否已經(jīng)用完;

2、若未用完,則直接在備用空間上插入元素,并更新元素尾指針;

3、若已經(jīng)用完,則重新分配內(nèi)存,并將舊元素復(fù)制到新的地址空間,然后插入新元素。

其中,vector對于空間的增長方式為:

    const size_type __len = __old_size != 0 ? 2 * __old_size : 1;

即初始時,vector的空間為1,后續(xù)每次都會以舊空間的2倍增長。

clear

void clear() { erase(begin(), end()); }
// 清除 [first, last) 中的所有元素
iterator erase(iterator __first, iterator __last) {
    iterator __i = copy(__last, _M_finish, __first);
    destroy(__i, _M_finish);
    _M_finish = _M_finish - (__last - __first);
    return __first;
}

clear是通過調(diào)用erase函數(shù)來完成的,其中,在清除元素時,erase函數(shù)會將未被清除的元素拷貝的vector頭部,然后依次釋放后面的空間,我們不再過多贅述。

特點

1、vector使用的是內(nèi)存中連續(xù)的地址空間,如果已分配的內(nèi)存空間不夠使用時,則vector會以舊容量的2倍來進行擴充,這些都是vector內(nèi)部來完成的,不需要我們?nèi)タ刂疲?/p>

2、vector具有隨機訪問的能力,訪問節(jié)點的效率很高,vector對[]的重載函數(shù)為

reference operator[](size_type __n) { return *(begin() + __n); }  // 重載 [],訪問指定的元素 
iterator begin() { return _M_start; }   // 返回指向容器第一個元素的迭代器 

其中,_M_start為原生指針,原生指針屬于Random access iterator,所以,vector具備了隨機訪問元素的能力。

到此這篇關(guān)于STL容器之vector源碼詳細解讀的文章就介紹到這了,更多相關(guān)vector源碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言實現(xiàn)輸出鏈表中倒數(shù)第k個節(jié)點

    C語言實現(xiàn)輸出鏈表中倒數(shù)第k個節(jié)點

    這篇文章主要介紹了C語言實現(xiàn)輸出鏈表中倒數(shù)第k個節(jié)點,主要涉及鏈表的遍歷操作,是數(shù)據(jù)結(jié)構(gòu)中鏈表的常見操作。需要的朋友可以參考下
    2014-09-09
  • C/C++ 運用Npcap發(fā)送UDP數(shù)據(jù)包的完美過程

    C/C++ 運用Npcap發(fā)送UDP數(shù)據(jù)包的完美過程

    UDP 是一種無連接、輕量級的傳輸層協(xié)議,與 TCP 相比,它不提供可靠性、流控制和錯誤恢復(fù)機制,但卻更加簡單且具有較低的開銷,這篇文章主要介紹了C/C++ 運用Npcap發(fā)送UDP數(shù)據(jù)包,需要的朋友可以參考下
    2023-11-11
  • Qt 數(shù)據(jù)庫QSqlDatabase使用示例

    Qt 數(shù)據(jù)庫QSqlDatabase使用示例

    本文主要介紹了Qt數(shù)據(jù)庫QSqlDatabase使用示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-12-12
  • 實現(xiàn)去除c語言注釋的小工具

    實現(xiàn)去除c語言注釋的小工具

    這篇文章主要介紹了實現(xiàn)去除c語言注釋的小工具,說是C語言,但其實所有C語系的都可以,比如Java,需要的朋友可以參考下
    2014-02-02
  • C++實現(xiàn)自定義撤銷重做功能的示例代碼

    C++實現(xiàn)自定義撤銷重做功能的示例代碼

    在使用c++做界面開發(fā)的時候,尤其是實現(xiàn)白板功能時需要自己實現(xiàn)一套撤銷重做功能.如果是qt則有QUndoable對象,可以直接拿來用。但是如果是使用gdi繪圖,則可能需要自己實現(xiàn)了。本文就來用C++實現(xiàn)自定義撤銷重做功能,需要的可以參考一下
    2022-12-12
  • C++ 中消息隊列函數(shù)實例詳解

    C++ 中消息隊列函數(shù)實例詳解

    這篇文章主要介紹了C++ 中消息隊列函數(shù)實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • C++中Digraphs、Trigraphs和Tokens的深入講解

    C++中Digraphs、Trigraphs和Tokens的深入講解

    這篇文章主要給大家介紹了關(guān)于C++中Digraphs、Trigraphs和Tokens的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • C++選擇文件夾代碼的封裝

    C++選擇文件夾代碼的封裝

    這篇文章主要介紹了C++選擇文件夾代碼的封裝,實例展示了將選擇文件夾功能代碼封裝為一個類并對其進行實例化調(diào)用的過程,對于學(xué)習(xí)C++程序設(shè)計有不錯的參考價值,需要的朋友可以參考下
    2014-10-10
  • C語言求質(zhì)數(shù)的幾種簡單易懂方式

    C語言求質(zhì)數(shù)的幾種簡單易懂方式

    這篇文章主要介紹了C語言求質(zhì)數(shù)的幾種簡單易懂方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • C++初始化函數(shù)列表詳細解析

    C++初始化函數(shù)列表詳細解析

    C++可以定義引用類型的成員變量,引用類型的成員變量必須在構(gòu)造函數(shù)的初始化列表中進行初始化
    2013-09-09

最新評論