vector源碼剖析

一、vector定義摘要:

template <class T, class Alloc = alloc>
class vector {
public:typedef T                   value_type;typedef value_type*         pointer;typedef const value_type*   const_pointer;typedef value_type*         iterator;typedef const value_type*   const_iterator;typedef value_type&         reference;typedef const value_type&   const_reference;typedef size_t              size_type;typedef ptrdiff_t           difference_type;
protected:typedef simple_alloc<value_type, Alloc> data_allocator;iterator start;iterator finish;iterator end_of_storage;
public:iterator begin() { return start; }const_iterator begin() const { return start; }iterator end() { return finish; }const_iterator end() const { return finish; }size_type size() const { return size_type(end() - begin()); }size_type max_size() const { return size_type(-1) / sizeof(T); }size_type capacity() const { return size_type(end_of_storage - begin()); }bool empty() const { return begin() == end(); }reference operator[](size_type n) { return *(begin() + n); }const_reference operator[](size_type n) const { return *(begin() + n); }vector() : start(0), finish(0), end_of_storage(0) {}vector(size_type n, const T & value) { fill_initialize(n, value); }vector(int n, const T & value) { fill_initialize(n, value); }vector(long n, const T & value) { fill_initialize(n, value); }explicit vector(size_type n) { fill_initialize(n, T()); }
};

?

二、構造函數 :

vector() : start(0), finish(0), end_of_storage(0) {}
vector(size_type n, const T& value) { fill_initialize(n, value); }template <class T, class Alloc>
void vector<T, Alloc>::::fill_initialize(size_type n, const T& value)
{start = allocate_and_fill(n, value);finish = start + n;end_of_storage = finish;
}template <class T, class Alloc>
iterator vector<T, Alloc>::allocate_and_fill(size_type n, const T& x)
{iterator result = data_allocator::allocate(n);uninitialized_fill_n(result, n, x);return result;
}vector(const vector<T, Alloc>& x) 
{start = allocate_and_copy(x.end() - x.begin(), x.begin(), x.end());finish = start + (x.end() - x.begin());end_of_storage = finish;
}iterator allocate_and_copy(size_type n, const_iterator first, const_iterator last)
{iterator result = data_allocator::allocate(n);uninitialized_copy(first, last, result);return result;
}

?

三、析構函數:

template <class T, class Alloc>
vector<T, Alloc>::~vector()
{destroy(start, finish);deallocate();
}template <class T, class Alloc>
void vector<T, Alloc>::deallocate()
{if (start)data_allocator::deallocate(start, end_of_storage - start);
}

?

四、push_back

template <class T, class Alloc>
void vector<T>::push_back(const T& x) //重點函數
{if (finish != end_of_storage) //還有備用空間{construct(finish, x);  //全局函數++finish;}elseinsert_aux(end(), x); //已經沒有備用空間
}template <class T, class Alloc>
void vector<T>::insert_aux(iterator position, const T& x)
{if (finish != end_of_storage) //還有備用空間{construct(finish, *(finish - 1));++finish;T x_copy = x;std::copy_backward(position, finish - 2, finish - 1);*position = x_copy;}else //沒有備用空間了{const size_type old_size = size();const size_type len = old_size != 0 ? 2 * old_size : 1;//以上配置原則:如果原大小為0,則配置1//如果原大小不為0,則配置原大小2倍//前半段用來放置原數據,后半段放置新數據iterator new_start = data_allocator::allocate(len);iterator new_finish = new_start;new_finish = uninitialized_copy(start, position, new_start);construct(new_finish, x);++new_finish;new_finish = uninitialized_copy(position, finish, new_finish);destroy(begin(), end());deallocate();start = new_start;finish = new_finish;end_of_storage = new_start + len;}
}

?

vetor的元素操作:pop_back、erase、clear、insert

void pop_back()
{--finish;         //將尾標記往前移動一格,表示將放棄尾端元素destroy(finish); //析構函數
}iterator erase(iterator first, iterator last)
{iterator i = copy(last, finish, first);destroy(i, finish);finish = finish - (last - first);return first;
}iterator erase(iterator position)
{if (position + 1 != end())copy(position + 1, finish, position);--finish;destroy(finish);return position;
}void clear() { erase(begin(), end()); }template <class T, class Alloc>
void vector<T, Alloc>::insert(iterator position, size_type n, const T & x)
{if (n != 0) //當n!= 0才進行以下所有操作{if (size_type(end_of_storage - finish) >= n) //備用空間大于等于新增元素{T x_copy = x;const size_type elems_after = finish - position; //計算插入點之后的現有元素個數iterator old_finish = finish;if (elems_after > n) //"插入點之后的現有元素個數"大于"新增元素個數"{uninitialized_copy(finish - n, finish, finish);finish += n;copy_backward(position, old_finish - n, old_finish);fill(position, position + n, x_copy);}else //"插入點之后的現有元素個數"小于等于"新增元素個數"{uninitialized_fill_n(finish, n - elems_after, x_copy);finish += n - elems_after;uninitialized_copy(position, old_finish, finish);finish += elems_after;fill(position, old_finish, x_copy);}}else{//備用空間小于"新增元素個數"(那就必須配置額外的內存)//首先決定新長度:舊長度的兩倍,或舊長度+新增元素個數const size_type old_size = size();const size_type len = old_size + max(old_size, n);iterator new_start = data_allocator::allocate(len);iterator new_finish = new_start;new_finish = uninitialized_copy(start, position, new_start);new_finish = uninitialized_fill_n(new_finish, n, x);new_finish = uninitialized_copy(position, finish, new_finish);destroy(start, finish);deallocate();start = new_start;finish = new_finish;end_of_storage = new_start + len;}}
}

?

五、resize、reverse

void resize(size_type new_size, const T& x)
{if (new_size < size())erase(begin() + new_size, end());elseinsert(end(), new_size - size(), x);
}
void resize(size_type new_size) { resize(new_size, T()); }void reserve(size_type n) 
{if (capacity() < n) {const size_type old_size = size();iterator tmp = allocate_and_copy(n, start, finish);destroy(start, finish);deallocate();start = tmp;finish = tmp + old_size;end_of_storage = start + n;}
}iterator allocate_and_copy(size_type n, const_iterator first, const_iterator last)
{iterator result = data_allocator::allocate(n);uninitialized_copy(first, last, result);return result;
}

?

六、 swap

 void swap(vector<T, Alloc>& x) 
{__STD::swap(start, x.start);__STD::swap(finish, x.finish);__STD::swap(end_of_storage, x.end_of_storage);}

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/385266.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/385266.shtml
英文地址,請注明出處:http://en.pswp.cn/news/385266.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vs2013編譯win-32位下的libevent-2.0.21-stable,debug版本

環境&#xff1a;win10&#xff08;64位&#xff09;vs2013 首先需要修改Makefile.nmake中的CFLAGS$(CFLAGS) /Ox /W3 /wd4996 /nologo注釋掉&#xff0c;這一行是不帶調試信息的。CFLAGS$(CFLAGS) /Od /W3 /wd4996 logo /Zi 替換這一行之后就可以自帶調試信息。 打開vs2013的…

Leetcode 219. 存在重復元素 II

解題思路&#xff1a; class Solution { public:bool containsNearbyDuplicate(vector<int>& nums, int k) {unordered_map<int, int> cnt;for(int i0; i<nums.size(); i){if(cnt.find(nums[i]) ! cnt.end()){if(i - cnt[nums[i]] < k) return true;}cn…

Linux程序設計01:開發工具和開發平臺

1.SecureCRT 1.1SecureCRT支持SSH*&#xff08;SSH1和SSH2&#xff09;&#xff0c;安裝的過程不在贅述 1.2與SecureCRT相關的Linux命令 rz和sz是Linux同windows進行ZModem文件傳輸的命令行工具。 sz命令利用ZModem協議來從Linux服務器傳送文件到本地&#xff0c;一次可以傳送一…

fork、vfork、clone

1. 概念 寫時復制技術最初產生于Unix系統&#xff0c;用于實現一種傻瓜式的進程創建&#xff1a;當發出fork( )系統調用時&#xff0c;內核原樣復制父進程的整個地址空間并把復制的那一份分配給子進程。這種行為是非常耗時的&#xff0c;因為它需要&#xff1a; 為子進程的頁…

Linux02進程內存管理

1.進程地址空間 1.1程序的結構與進程的結構 [rootlocalhost demo]# size testtext data bss dec hex filename 1193 492 16 1701 6a5 test 一個可執行程序包含三個部分&#xff1a; 代碼段&#xff1a;主要存放指令&#xff0c;操作以及只讀的常量數據例…

epoll

開發高性能網絡程序時&#xff0c;windows開發者們言必稱iocp&#xff0c;linux開發者們則言必稱epoll。大家都明白epoll是一種IO多路復用技術&#xff0c;可以非常高效的處理數以百萬計的socket句柄&#xff0c;比起以前的select和poll效率高大發了。我們用起epoll來都感覺挺爽…

劍指offer目錄

序號題目1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

基于升序鏈表的定時器

#ifndef LST_TIMER#define LST_TIMER#include <time.h>#define BUFFER_SIZE 64class util_timer;//用戶數據結構&#xff1a;客戶端地址、客戶端的socket、socket文件描述符、讀緩存和定時器struct client_data{sockaddr_in address;int sockfd;char buf[ BUFFER_SIZE ];…

SIGCHLD信號使用和注意事項

1.SIGCHLD簡介 SIGCHILD是指在一個進程終止或者停止時&#xff0c;將SIGCHILD信號發送給其父進程&#xff0c;按照系統默認將忽略此信號&#xff0c;如果父進程希望被告知其子系統的這種狀態&#xff0c;則應捕捉此信號。注意&#xff1a;SIGCLD信號與其長得非常相似。SIGCLD是…

08-圖7 公路村村通 (30 分

現有村落間道路的統計數據表中&#xff0c;列出了有可能建設成標準公路的若干條道路的成本&#xff0c;求使每個村落都有公路連通所需要的最低成本。 輸入格式: 輸入數據包括城鎮數目正整數N&#xff08;≤&#xff09;和候選道路數目M&#xff08;≤&#xff09;&#xff1b;隨…

【Leetcode】33. 搜索旋轉排序數組

假設按照升序排序的數組在預先未知的某個點上進行了旋轉。 ( 例如&#xff0c;數組 [0,1,2,4,5,6,7] 可能變為 [4,5,6,7,0,1,2] )。 搜索一個給定的目標值&#xff0c;如果數組中存在這個目標值&#xff0c;則返回它的索引&#xff0c;否則返回 -1 。 你可以假設數組中不存在重…

08-圖9 關鍵活動 (30 分

假定一個工程項目由一組子任務構成&#xff0c;子任務之間有的可以并行執行&#xff0c;有的必須在完成了其它一些子任務后才能執行。“任務調度”包括一組子任務、以及每個子任務可以執行所依賴的子任務集。 比如完成一個專業的所有課程學習和畢業設計可以看成一個本科生要完成…

【Leetocde | 10 】54. 螺旋矩陣

解題代碼&#xff1a; class Solution { public:vector<int> spiralOrder(vector<vector<int>>& matrix) {if (matrix.empty() || matrix[0].empty()) return {};int m matrix.size(), n matrix[0].size();vector<int> res;int up 0, down m …

09-排序1 排序 (25 分)

給定N個&#xff08;長整型范圍內的&#xff09;整數&#xff0c;要求輸出從小到大排序后的結果。 本題旨在測試各種不同的排序算法在各種數據情況下的表現。各組測試數據特點如下&#xff1a; 數據1&#xff1a;只有1個元素&#xff1b; 數據2&#xff1a;11個不相同的整數…

網絡層

1. 簡單解釋一些ARP協議的工作過程

【Leetocde | 24 】152. 乘積最大子序列

這道題最直接的方法就是用DP來做&#xff0c;而且要用兩個dp數組&#xff0c;其中f[i]表示子數組[0, i]范圍內并且一定包含nums[i]數字的最大子數組乘積&#xff0c;g[i]表示子數組[0, i]范圍內并且一定包含nums[i]數字的最小子數組乘積&#xff0c;初始化時f[0]和g[0]都初始化…

【Leetcode | 1】3. 無重復字符的最長子串

這里我們可以建立一個HashMap&#xff0c;建立每個字符和其最后出現位置之間的映射&#xff0c;然后我們需要定義兩個變量res和left&#xff0c;其中res用來記錄最長無重復子串的長度&#xff0c;left指向該無重復子串左邊的起始位置的前一個&#xff0c;由于是前一個&#xff…

【Leetcode | 】93. 復原IP地址

class Solution { public:vector<string> strs;//用于存放臨時的四個段vector<string> result;//存放結果void dfs(string &s, int beginIndex, int step) {if (step 4 && beginIndex s.size()) //搜索成功{string temRec strs[0] "." …

海量數據(一)

1. 有1億個浮點數&#xff0c;如果找出期中最大的10000個&#xff1f; 最容易想到的方法是將數據全部排序&#xff0c;然后在排序后的集合中進行查找&#xff0c;最快的排序算法的時間復雜度一般為O&#xff08;nlogn&#xff09;&#xff0c;如快速排序。但是在32位的機器上&a…

1018 錘子剪刀布 (20 分)

大家應該都會玩“錘子剪刀布”的游戲&#xff1a;兩人同時給出手勢&#xff0c;勝負規則如圖所示&#xff1a; 現給出兩人的交鋒記錄&#xff0c;請統計雙方的勝、平、負次數&#xff0c;并且給出雙方分別出什么手勢的勝算最大。 輸入格式&#xff1a; 輸入第 1 行給出正整數 N…