1. 程式人生 > >【C++】std::vector原始碼淺析

【C++】std::vector原始碼淺析

std::vector是stl標準模板庫中的一個序列容器,其原始碼實現有幾個特點:

(1)C++中include的標準標頭檔案是沒有“.h”字尾的,其實這是C++的一層包裹,內部實現還是在“.h”檔案中完成的,以我們include的vector為例,其中還會include一些真正的vector實現檔案,如“stl_vector.h”。

(2)vector的實現有一些內部使用的函式和資料型別,它們以下劃線“_”開頭。

(3)vector是個模板類,繼承自_Vector_base,_Vector_base是個struct,它有一個巢狀的struct為_Vector_impl,其中有三個關鍵的指標成員變數,_M_start,_M_finish,_M_end_of_storage,明白這三個變數對vector的理解很有幫助。

(4)我們通常使用的vector介面,大部分是通過形如“_M_xxx”的內部函式實現的。

(5)vector的操作符首先實現了判等“==”和小於“<”,其它的操作符都是基於這兩個操作符實現的。

(6)vector中有一些C++11引入的語法,可在原始碼中茶看得到。

下面看一下原始碼中的“vector”和“stl_vector.h”都有什麼內容。

/* vector */

//>標頭檔案普遍都有的巨集保護, 防止多重include
//>GNU C++ Library, 即libstdc++.so, 而非libc++.so
//>lib庫名不同也就是GNU與標準C++的不同實現的區別
#ifndef _GLIBCXX_VECTOR #define _GLIBCXX_VECTOR 1 //>pragma預處理用法 //>告訴GCC該位置下面的include為系統標頭檔案 //>不影響該位置上面的部分 #pragma GCC system_header /* 從下面的include可以看出, 有多個不同型別的vector. */ //>演算法相關的模板函式 #include <bits/stl_algobase.h> //>用於記憶體分配的模板類 //>typedef了許多常見的資料型別 #include <bits/allocator.h>
//>非標準的物件建立/銷燬的模板函式 //>如_Construct/_Destroy #include <bits/stl_construct.h> //>操作原始記憶體的模板函式 //>從標頭檔案的名字就可以看出, 函式並不初始化記憶體 #include <bits/stl_uninitialized.h> //>正宗的vector模版類 #include <bits/stl_vector.h> //>vector模板類的特化版本 //>用bool特化的vector模板, 即vector<bool> #include <bits/stl_bvector.h> //>模板函式, 獲取迭代器Iterator的begin/end #include <bits/range_access.h> //>tcc版vector #ifndef _GLIBCXX_EXPORT_TEMPLATE # include <bits/vector.tcc> #endif //>debug版vector #ifdef _GLIBCXX_DEBUG # include <debug/vector> #endif //>profile版vector #ifdef _GLIBCXX_PROFILE # include <profile/vector> #endif #endif /* _GLIBCXX_VECTOR */ /* stl_vector.h */ //>標頭檔案普遍都有的巨集保護 #ifndef _STL_VECTOR_H #define _STL_VECTOR_H 1 //>Iterator迭代器通用的函式, 如distance/advance/next/prev #include <bits/stl_iterator_base_funcs.h> //>異常控制的幾個函式宣告 #include <bits/functexcept.h> //>一些精巧的巨集定義,typedef了一些資料型別 #include <bits/concept_check.h> //>__cplusplus C++版本 #if __cplusplus >= 201103L //>initializer_list模板類 //>C++11引入的, 初始化列表, 提供了迭代器 #include <initializer_list> #endif //>_GLIBCXX_VISIBILIT在c++config.h中有定義 //>簡單來說即__attribute__((__visibility__("default"))) //>這個是gcc __attribute__的用法 //>詳細定義如下 /*********** #define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY 1 #if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY # define _GLIBCXX_VISIBILITY(V) __attribute__((__visibility__(#V))) #else # define _GLIBCXX_VISIBILITY(V) _GLIBCXX_PSEUDO_VISIBILITY(V) #endif #ifndef _GLIBCXX_PSEUDO_VISIBILITY # define _GLIBCXX_PSEUDO_VISIBILITY(V) #endif **********/ namespace std _GLIBCXX_VISIBILITY(default) { //>_GLIBCXX_BEGIN_NAMESPACE_CONTAINER在c++config.h中有定義 //>這裡即一個空的巨集定義 //>詳細定義如下 /********** #if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PROFILE) # define _GLIBCXX_STD_C __cxx1998 # define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER \ namespace _GLIBCXX_STD_C { _GLIBCXX_BEGIN_NAMESPACE_VERSION # define _GLIBCXX_END_NAMESPACE_CONTAINER \ } _GLIBCXX_END_NAMESPACE_VERSION #endif #ifndef _GLIBCXX_STD_C # define _GLIBCXX_STD_C std #endif #ifndef _GLIBCXX_BEGIN_NAMESPACE_CONTAINER # define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER #endif #ifndef _GLIBCXX_END_NAMESPACE_CONTAINER # define _GLIBCXX_END_NAMESPACE_CONTAINER #endif #define _GLIBCXX_INLINE_VERSION 0 #if _GLIBCXX_INLINE_VERSION # define _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __7 { # define _GLIBCXX_END_NAMESPACE_VERSION } #else # define _GLIBCXX_BEGIN_NAMESPACE_VERSION # define _GLIBCXX_END_NAMESPACE_VERSION #endif **********/ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER //>_Vector_base為vector的基類, 模板類 //>_Tp是個具體的型別 //>_Alloc為記憶體分配器, 可參照std::allocator template<typename _Tp, typename _Alloc> struct _Vector_base { //>typedef定義型別的別名 //>typename表示其後的內容是個型別, 否則會被當作普通欄位 //>__gnu_cxx名字空間中的__alloc_traits是allocator的統一介面 //>_Tp_alloc_type定義的簡單形式如下 //>typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type; //>如果模板引數_Alloc為std::allocator的話, _Tp_alloc_type的定義如下 //>typedef typename allocator<_Tp> _Tp_alloc_type; typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Tp>::other _Tp_alloc_type; //>同上, pointer即typedef typename _Tp_alloc_type::pointer pointer; //>同上, 如果模板引數_Alloc為std::allocator的話, pointer將非常簡單, 如下所示 //>typedef typename _Tp* pointer; //>繞了一大圈, 其實很簡單! typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer pointer; //>巢狀struct //>_Vector_base implementation struct _Vector_impl : public _Tp_alloc_type { //>三個重要的指標成員變數, 貫穿於整個vector //>用集合的方法表示vector就是[_M_start, _M_finish) //>指向vector中第一個元素的地址 pointer _M_start; //>指向vector中最後一個元素的下一個位置的地址 pointer _M_finish; //>指向vector的容量的末地址 pointer _M_end_of_storage; //>建構函式的兩個版本 //>初始化列表中呼叫了對應的基類建構函式 //>初始化列表中初始化了各指標成員變數, 且初始化順序與變數宣告的順序保持一致 _Vector_impl() : _Tp_alloc_type(), _M_start(0), _M_finish(0), _M_end_of_storage(0) { } _Vector_impl(_Tp_alloc_type const& __a) : _Tp_alloc_type(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) { } #if __cplusplus >= 201103L //>符號&&即rvalue, 右值引用, C++11引進的, 呼叫std::move //>符號&即lvalue, 傳統的左值引用 _Vector_impl(_Tp_alloc_type&& __a) : _Tp_alloc_type(std::move(__a)), _M_start(0), _M_finish(0), _M_end_of_storage(0) { } #endif //>資料交換, 引數型別為&, 直接呼叫了std::swap //>交換的是三個指標成員變數 void _M_swap_data(_Vector_impl& __x) { std::swap(_M_start, __x._M_start); std::swap(_M_finish, __x._M_finish); std::swap(_M_end_of_storage, __x._M_end_of_storage); } }; //> struct _Vector_impl public: //>stl中多處使用了typedef, 目的就是讓資料型別更加簡單、具體 typedef _Alloc allocator_type; //>非const版本與const版本的_M_get_Tp_allocator //>使用static_cast把子類指標轉化為父類指標, 即up-cast, 型別安全 //>_GLIBCXX_NOEXCEPT即異常相關的巨集定義 /********** #ifndef _GLIBCXX_NOEXCEPT # if __cplusplus >= 201103L # define _GLIBCXX_NOEXCEPT noexcept # else # define _GLIBCXX_NOEXCEPT # endif #endif **********/ //>noexcept是C++11引進的, 即不丟擲任何異常, 等價於throw() _Tp_alloc_type& _M_get_Tp_allocator() _GLIBCXX_NOEXCEPT { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); } const _Tp_alloc_type& _M_get_Tp_allocator() const _GLIBCXX_NOEXCEPT { return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); } //>獲取allocator_type物件 //>可理解為_Alloc<_Tp>型別的物件 //>呼叫了某個版本的建構函式 allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return allocator_type(_M_get_Tp_allocator()); } //>下面是幾個版本的建構函式 _Vector_base() : _M_impl() { } _Vector_base(const allocator_type& __a) : _M_impl(__a) { } //>引數__n指定了vector大小 //>呼叫_M_create_storage分配記憶體 _Vector_base(size_t __n) : _M_impl() { _M_create_storage(__n); } _Vector_base(size_t __n, const allocator_type& __a) : _M_impl(__a) { _M_create_storage(__n); } #if __cplusplus >= 201103L //>rvalue版本的幾個建構函式 _Vector_base(_Tp_alloc_type&& __a) : _M_impl(std::move(__a)) { } _Vector_base(_Vector_base&& __x) : _M_impl(std::move(__x._M_get_Tp_allocator())) { this->_M_impl._M_swap_data(__x._M_impl); } _Vector_base(_Vector_base&& __x, const allocator_type& __a) : _M_impl(__a) { if (__x.get_allocator() == __a) this->_M_impl._M_swap_data(__x._M_impl); else { size_t __n = __x._M_impl._M_finish - __x._M_impl._M_start; _M_create_storage(__n); } } #endif //>析構, 記憶體釋放, 最終會呼叫到::operator delete操作符 ~_Vector_base() { _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); } public: //>成員變數型別為內嵌的struct, 一種簡單的設計模式 _Vector_impl _M_impl; //>記憶體分配, 最終會呼叫到::operator new操作符 pointer _M_allocate(size_t __n) { return __n != 0 ? _M_impl.allocate(__n) : 0; } //>記憶體釋放 void _M_deallocate(pointer __p, size_t __n) { if (__p) _M_impl.deallocate(__p, __n); } private: //>私有的建立儲存空間的函式 //>呼叫上面的_M_Allocate來分配記憶體 void _M_create_storage(size_t __n) { this->_M_impl._M_start = this->_M_allocate(__n); this->_M_impl._M_finish = this->_M_impl._M_start; this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; } }; //>真正的vector模板類, _Alloc預設型別為std::vector<_Tp> template<typename _Tp, typename _Alloc = std::allocator<_Tp> > //>protected方式繼承自_Vector_base, 繼承下來的public內容會將級至protected //>_Vector_base為struct, 預設的訪問級別為public class vector : protected _Vector_base<_Tp, _Alloc> { //>_Alloc_value_type即_Tp typedef typename _Alloc::value_type _Alloc_value_type; //>concept_check.h中的巨集, 作型別檢查, 從最後一個引數可以看出對型別作何檢查 __glibcxx_class_requires(_Tp, _SGIAssignableConcept) __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) //>_Base為vector基類的型別 typedef _Vector_base<_Tp, _Alloc> _Base; //>_Tp_alloc_type可理解為_Alloc<_Tp> typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits; public: //>typedef常用的資料型別 //>_Tp typedef _Tp value_type; //>Tp* typedef typename _Base::pointer pointer; //>const Tp* typedef typename _Alloc_traits::const_pointer const_pointer; //>_Tp& typedef typename _Alloc_traits::reference reference; //>const _Tp& typedef typename _Alloc_traits::const_reference const_reference; //>iterator typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator; //>const_iterator typedef __gnu_cxx::__normal_iterator<const_pointer, vector> const_iterator; //>const_reverse_iterator typedef std::reverse_iterator<const_iterator> const_reverse_iterator; //>reverse_iterator typedef std::reverse_iterator<iterator> reverse_iterator; /********** namespace std { typedef __SIZE_TYPE__ size_t; typedef __PTRDIFF_TYPE__ ptrdiff_t; } **********/ typedef size_t size_type; typedef std::ptrdiff_t difference_type; //>_Alloc typedef _Alloc allocator_type; protected: //>using常用於namespapce //>這個地方的using使用了基類的成員, 甚至可以使用基類的private成員 //>C++11還引進了using的其它用法, 類似於typedef using _Base::_M_allocate; using _Base::_M_deallocate; using _Base::_M_impl; using _Base::_M_get_Tp_allocator; public: //>預設建構函式, vector為空 vector() : _Base() { } //>指定_Alloc的建構函式, vector也為空 //>explicit關鍵字, 建構函式可以傳遞一個引數時的慣用法, 防止型別隱式轉換 explicit vector(const allocator_type& __a) : _Base(__a) { } #if __cplusplus >= 201103L //>建構函式, 指定了vector大小和預設的記憶體分配器 //>vector採取了預設的初始化方式, 呼叫_M_default_initialize explicit vector(size_type __n, const allocator_type& __a = allocator_type()) : _Base(__n, __a) { _M_default_initialize(__n); } //>建構函式, 指定了vector大小、元素型別和預設的記憶體分配器 //>通過指定的value_type初始化vector, 呼叫_M_fill_initialize vector(size_type __n, const value_type& __value, const allocator_type& __a = allocator_type()) : _Base(__n, __a) { _M_fill_initialize(__n, __value); } #else //>建構函式, 指定了vector大小、預設的元素型別和預設的記憶體分配器 //>同樣, 呼叫_M_fill_initialize進行初始化 explicit vector(size_type __n, const value_type& __value = value_type(), const allocator_type& __a = allocator_type()) : _Base(__n, __a) { _M_fill_initialize(__n, __value); } #endif //>拷貝建構函式 //>拷貝了同樣的元素和記憶體分配器 vector(const vector& __x) : _Base(__x.size(), _Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator())) { this->_M_impl._M_finish = std::__uninitialized_copy_a(__x.begin(), __x.end(), this->_M_impl._M_start, _M_get_Tp_allocator()); } #if __cplusplus >= 201103L //>rvalue版本的建構函式 //>noexcept不丟擲任何異常 //>呼叫了std::move vector(vector&& __x) noexcept : _Base(std::move(__x)) { } //>指定了記憶體分配器的copy constructor //>呼叫了std::__uninitialized_copy_a vector(const vector& __x, const allocator_type& __a) : _Base(__x.size(), __a) { this->_M_impl._M_finish = std::__uninitialized_copy_a(__x.begin(), __x.end(), this->_M_impl._M_start, _M_get_Tp_allocator()); } //>指定了記憶體分配器的move constructor //>當記憶體分配器不同時才進行真正的拷貝 vector(vector&& __rv, const allocator_type& __m) : _Base(std::move(__rv), __m) { if (__rv.get_allocator() != __m) { this->_M_impl._M_finish = std::__uninitialized_move_a(__rv.begin(), __rv.end(), this->_M_impl._M_start, _M_get_Tp_allocator()); __rv.clear(); } } //>初始化列表形式的建構函式, 會呼叫value_type型別的拷貝建構函式 //>呼叫了_M_range_initialize vector(initializer_list<value_type> __l, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_range_initialize(__l.begin(), __l.end(), random_access_iterator_tag()); } #endif #if __cplusplus >= 201103L //>函式引數為迭代器的模板建構函式, 以及預設的記憶體分配器 //>呼叫了_M_initialize_dispatch進行初始化 template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator> > vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_initialize_dispatch(__first, __last, __false_type()); } #else template<typename _InputIterator> vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_initialize_dispatch(__first, __last, _Integral()); } #endif //>解構函式, 清空vector中的元素 //>需要注意的是, 如果vector中的元素為指標的話, 指標指向的記憶體需要我們自己管理 ~vector() _GLIBCXX_NOEXCEPT { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); } //>賦值操作符 vector& operator=(const vector& __x); #if __cplusplus >= 201103L //>rvalue版本的賦值操作符 //>constexpr是C++11引入的, 常量表達式 //>呼叫了_M_move_assign vector& operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) { constexpr bool __move_storage = _Alloc_traits::_S_propagate_on_move_assign() || _Alloc_traits::_S_always_equal(); _M_move_assign(std::move(__x), integral_constant<bool, __move_storage>()); return *this; } //>引數為initializer_list的賦值操作符 //>直接呼叫assign進行賦值 vector& operator=(initializer_list<value_type> __l) { this->assign(__l.begin(), __l.end()); return *this; } #endif //>下面是幾個版本的賦值函式assign //>新的資料會覆蓋vector中原來的資料 //>指定了vector的長度和元素型別, 呼叫了_M_fill_assign void assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); } #if __cplusplus >= 201103L //>assign引數為迭代器的模板函式 //>呼叫_M_assign_dispatch template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> void assign(_InputIterator __first, _InputIterator __last) { _M_assign_dispatch(__first, __last, __false_type()); } #else template<typename _InputIterator> void assign(_InputIterator __first, _InputIterator __last) { typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_assign_dispatch(__first, __last, _Integral()); } #endif #if __cplusplus >= 201103L //>引數為initializer_list //>直接呼叫迭代器版本的assign函式, 程式碼簡潔之道 void assign(initializer_list<value_type> __l) { this->assign(__l.begin(), __l.end()); } #endif //>使用基類的分配器 using _Base::get_allocator; //>下面是幾個不同版本的begin/end函式 //>用於獲取不同版本的迭代器iterator/const_iterator //>begin返回的是指向vector第一個元素的迭代器 //>end返回的是指向vector最後一個元素的下一個位置的迭代器 iterator begin() _GLIBCXX_NOEXCEPT { return iterator(this->_M_impl._M_start); } const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(this->_M_impl._M_start); } iterator end() _GLIBCXX_NOEXCEPT { return iterator(this->_M_impl._M_finish); } const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(this->_M_impl._M_finish); } //>下面是幾個不同版本的rbegin/rend函式 //>rbegin/rend與begin/end不同, 函式實現呼叫了end/begin, 返回的是返向迭代器 //>用於獲取不同版本的迭代器reverse_iterator/const_reverse_iterator //>rbegin返回的是指向vector最後一個元素的迭代器 //>rend返回的是指向vector第一個元素的前一個位置的迭代器 reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { return reverse_iterator(end()); } const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(end()); } reverse_iterator rend() _GLIBCXX_NOEXCEPT { return reverse_iterator(begin()); } const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L //>下面是幾個const版本的迭代器函式 //>cbegin/cend/crbegin/crend const_iterator cbegin() const noexcept { return const_iterator(this->_M_impl._M_start); } const_iterator cend() const noexcept { return const_iterator(this->_M_impl._M_finish); } const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } #endif //>獲取vector實有的元素個數 size_type size() const _GLIBCXX_NOEXCEPT { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); } //>獲取vector可容納元素個數的最大值 //>但是這個最大值僅僅是個可能值, 有可能根本就達不到 size_type max_size() const _GLIBCXX_NOEXCEPT { return _Alloc_traits::max_size(_M_get_Tp_allocator()); } #if __cplusplus >= 201103L //>下面是幾個版本的resize, 重置vector大小 //>vector可能被截短或者以一定的方式追加元素 //>size變大時呼叫_M_default_append追加 //>size變小時呼叫_M_erase_at_end移除多餘的 void resize(size_type __new_size) { if (__new_size > size()) _M_default_append(__new_size - size()); else if (__new_size < size()) _M_erase_at_end(this->_M_impl._M_start + __new_size); } //>size變大時, 呼叫insert在vector尾端插入 void resize(size_type __new_size, const value_type& __x) { if (__new_size > size()) insert(end(), __new_size - size(), __x); else if (__new_size < size()) _M_erase_at_end(this->_M_impl._M_start + __new_size); } #else //>帶預設value_type的resize void resize(size_type __new_size, value_type __x = value_type()) { if (__new_size > size()) insert(end(), __new_size - size(), __x); else if (__new_size < size()) _M_erase_at_end(this->_M_impl._M_start + __new_size); } #endif #if __cplusplus >= 201103L //>調整vector容量 //>當capacity()大於size()時, 這個函式就起作用了 //>前者大小會減小為後者大小 //>通過_M_shrink_to_fit來實現 void shrink_to_fit() { _M_shrink_to_fit(); } #endif //>獲取vector的容量 //>從函式實現可以看出capacity不小於size size_type capacity() const _GLIBCXX_NOEXCEPT { return size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_start); } //>判斷vector是否為空 //>實現是通過迭代器判斷完成的 bool empty() const _GLIBCXX_NOEXCEPT { return begin() == end(); } //>重置vector的容量, 使其接近於size() //>當__n超過max_size()時會有異常std::length_error void reserve(size_type __n); //>元素訪問操作符, const與非const兩個版本 //>需要注意的是, 函式實現沒有檢查vector索引的有效性 //>vector索引有可能越界, 後果...斷錯誤 reference operator[](size_type __n) { return *(this->_M_impl._M_start + __n); } const_reference operator[](size_type __n) const { return *(this->_M_impl._M_start + __n); } protected: //>vector索引的有效性檢查, 用於at() //>索引越界時會丟擲std::out_of_range異常 void _M_range_check(size_type __n) const { if (__n >= this->size()) __throw_out_of_range(__N("vector::_M_range_check")); } public: //>元素訪問, const與非const兩個版本 //>呼叫了_M_range_check()進行索引的有效性檢查 reference at(size_type __n) { _M_range_check(__n); return (*this)[__n]; } const_reference at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; } //>front/back返回vector的第一個/最後一個元素 //>函式實現對是begin()/end()返回的迭代器取引用 //>如果vector為空的話, 函式返回的結果是不可預料的... reference front() { return *begin(); } const_reference front() const { return *begin(); } reference back() { return *(end() - 1); } const_reference back() const { return *(end() - 1); } //>獲取vector第一個元素, 返回指標 //>函式實現呼叫了front() #if __cplusplus >= 201103L _Tp* #else pointer #endif data() _GLIBCXX_NOEXCEPT { return std::__addressof(front()); } #if __cplusplus >= 201103L const _Tp* #else const_pointer #endif data() const _GLIBCXX_NOEXCEPT { return std::__addressof(front()); } //>追加一個元素到vector末尾 //>從函式實現可以看出, 當size()小於capacity()時 //>在vector末尾直接構建一個元素, 常量耗時 //>否則會根據__cplusplus版本做不同的事 void push_back(const value_type& __x) { if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) { _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, __x); ++this->_M_impl._M_finish; } else #if __cplusplus >= 201103L _M_emplace_back_aux(__x); #else _M_insert_aux(end(), __x); #endif } #if __cplusplus >= 201103L //>rvalue版本 //>通過emplace_back實現 void push_back(value_type&& __x) { emplace_back(std::move(__x)); } //>emplace_back與push_back不同 //>emplace_back是在vector末尾直接構建一個元素 //>而push_back是複製、移動一個元素到vector末尾 //>不定引數的模板函式 template<typename... _Args> void emplace_back(_Args&&... __args); #endif //>從vector末尾移除一個元素 //>操作的自然是_M_finish指標 void pop_back() { --this->_M_impl._M_finish; _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); } #if __cplusplus >= 201103L //>在__position前emplace一個元素 //>原理同emplace_back template<typename... _Args> iterator emplace(iterator __position, _Args&&... __args); #endif //>下面是幾個版本的insert //>在指定的位置插入元素 iterator insert(iterator __position, const value_type& __x); #if __cplusplus >= 201103L //>通過emplace來insert rvalue版本的元素 iterator insert(iterator __position, value_type&& __x) { return emplace(__position, std::move(__x)); } //>引數為initializer_list時直接呼叫迭代器版本的insert void insert(iterator __position, initializer_list<value_type> __l) { this->insert(__position, __l.begin(), __l.end()); } #endif //>呼叫_M_fill_insert void insert(iterator __position, size_type __n, const value_type& __x) { _M_fill_insert(__position, __n, __x); } //>迭代器版本的insert //>呼叫_M_insert_dispatch #if __cplusplus >= 201103L template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> void insert(iterator __position, _InputIterator __first, _InputIterator __last) { _M_insert_dispatch(__position, __first, __last, __false_type()); } #else template<typename _InputIterator> void insert(iterator __position, _InputIterator __first, _InputIterator __last) { typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_insert_dispatch(__position, __first, __last, _Integral()); } #endif //>erase移除指定位置的元素 iterator erase(iterator __position); //>erase移除指定範圍的元素 iterator erase(iterator __first, iterator __last); //>交換兩個vector中的內容 //>其實交換的就是_Vector_base::_Vector_impl中的三個指標 void swap(vector& __x) #if __cplusplus >= 201103L noexcept(_Alloc_traits::_S_nothrow_swap()) #endif { this->_M_impl._M_swap_data(__x._M_impl); _Alloc_traits::_S_on_swap(_M_get_Tp_allocator(), __x._M_get_Tp_allocator()); } //>清空vector //>呼叫_M_erase_at_end void clear() _GLIBCXX_NOEXCEPT { _M_erase_at_end(this->_M_impl._M_start); } protected: //>_M_allocate_and_copy //>從函式名可以看出 //>先allocate記憶體, 再copy資料 //>使用了異常處理 //>有異常時需要釋放剛才分配的記憶體並再次丟擲異常 //>__try/__catch/__throw_exception_again定義在exception_define.h中 /********** #ifndef __EXCEPTIONS // If -fno-exceptions, transform error handling code to work without it. # define __try if (true) # define __catch(X) if (false) # define __throw_exception_again #else // Else proceed normally. # define __try try # define __catch(X) catch(X) # define __throw_exception_again throw #endif **********/ template<typename _ForwardIterator> pointer _M_allocate_and_copy(size_type __n, _ForwardIterator __first, _ForwardIterator __last) { pointer __result = this->_M_allocate(__n); __try { std::__uninitialized_copy_a(__first, __last, __result, _M_get_Tp_allocator()); return __result; } __catch(...) { _M_deallocate(__result, __n); __throw_exception_again; } } //>_M_initialize_dispatch //>從函式名可以看出 //>分配了指定位元組的記憶體後需要進行初始化 //>初始化呼叫_M_fill_initialize template<typename _Integer> void _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type) { this->_M_impl._M_start = _M_allocate(static_cast<size_type>(__n)); this->_M_impl._M_end_of_storage = this->_M_impl._M_start + static_cast<size_type>(__n); _M_fill_initialize(static_cast<size_type>(__n), __value); } //>_M_initialize_dispatch //>迭代器版本 //>初始化呼叫_M_range_initialize template<typename _InputIterator> void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { typedef typename std::iterator_traits<_InputIterator>:: iterator_category _IterCategory; _M_range_initialize(__first, __last, _IterCategory()); } //>根據迭代器指向的內容初始化當前vector //>函式的第三個引數是個啞元 //>根據啞元型別的不同, 有兩個版本的_M_range_initialize template<typename _InputIterator> void _M_range_initialize(_InputIterator __first, _InputIterator __last, std::input_iterator_tag) { for (; __first != __last; ++__first) #if __cplusplus >= 201103L emplace_back(*__first); #else push_back(*__first); #endif } template<typename _ForwardIterator> void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag) { const size_type __n = std::distance(__first, __last); this->_M_impl._M_start = this->_M_allocate(__n); this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; this->_M_impl._M_finish = std::__uninitialized_copy_a(__first, __last, this->_M_impl._M_start, _M_get_Tp_allocator()); } //>_M_fill_initialize void _M_fill_initialize(size_type __n, const value_type& __value) { std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value, _M_get_Tp_allocator()); this->_M_impl._M_finish = this->_M_impl._M_end_of_storage; } #if __cplusplus >= 201103L //>_M_default_initialize void _M_default_initialize(size_type __n) { std::__uninitialized_default_n_a(this->_M_impl._M_start, __n, _M_get_Tp_allocator()); this->_M_impl._M_finish = this->_M_impl._M_end_of_storage; } #endif //>兩個_M_assign_dispatch函式 template<typename _Integer> void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) { _M_fill_assign(__n, __val); } template<typename _InputIterator> void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { typedef typename std::iterator_traits<_InputIterator>:: iterator_category _IterCategory; _M_assign_aux(__first, __last, _IterCategory()); } //>兩個_M_assign_aux函式 template<typename _InputIterator> void _M_assign_aux(_InputIterator __first, _InputIterator __last, std::input_iterator_tag); template<typename _ForwardIterator> void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag); //>_M_fill_assign void _M_fill_assign(size_type __n, const value_type& __val); //>兩個_M_insert_dispatch函式 template<typename _Integer> void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, __true_type) { _M_fill_insert(__pos, __n, __val); } template<typename _InputIterator> void _M_insert_dispatch(iterator __pos, _InputIterator __first, _InputIterator __last, __false_type) { typedef typename std::iterator_traits<_InputIterator>:: iterator_category _IterCategory; _M_range_insert(__pos, __first, __last, _IterCategory()); } //>兩個_M_range_insert函式 template<typename _InputIterator> void _M_range_insert(iterator __pos, _InputIterator __first, _InputIterator __last, std::input_iterator_tag); template<typename _ForwardIterator> void _M_range_insert(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag); //>_M_fill_insert void _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); #if __cplusplus >= 201103L //>用於resize(n) void _M_default_append(size_type __n); //>_M_shrink_to_fit bool _M_shrink_to_fit(); #endif #if __cplusplus < 201103L //>用於insert(p, x) void _M_insert_aux(iterator __position, const value_type& __x); #else template<typename... _Args> void _M_insert_aux(iterator __position, _Args&&... __args); //>_M_emplace_back_aux template<typename... _Args> void _M_emplace_back_aux(_Args&&... __args); #endif //>vector大小檢查 size_type _M_check_len(size_type __n, const char* __s) const { if (max_size() - size() < __n) __throw_length_error(__N(__s)); const size_type __len = size() + std::max(size(), __n); return (__len < size() || __len > max_size()) ?