C++模板之Vector與STL初探

STL源碼初步接觸ios

   STL = Standard Template Library,直譯過來是:標準模板庫,是惠普實驗室開發的一系列軟件的統稱。從根本上說,STL是一些「容器」的集合,這些「容器」有list,vector,set,map等,STL也是算法和其餘一些組件的集合。這裏的「容器」和算法的集合指的是世界上不少聰明人不少年的傑做。STL的目的是標準化組件,這樣就不用從新開發,可使用現成的組件。STL如今是C++的一部分,所以不用額外安裝什麼。STL所實現的,是依據泛型思惟架設起來的一個概念結構。說了這麼多仍是不知道STL是個什麼東東,今天只是初接觸這個概念,感受很高深的樣子,先這樣理解吧,STL就是一個倉庫,一個存放各類工具的倉庫。它的工具分爲六大類(六大組件) :算法

容器(containers):各類數據結構,如Vector,list,deque,set,map,用來存放底層數據。通常有序列式(下面要寫的Vector就是個這種)、關聯式等。數據結構

算法(algorithms):各類經常使用算法如:sort,search,copy,erase……函數

迭代器(iterator):扮演容器與算法之間的膠合劑,是所謂的「泛型指針」,共5種類型,以及他們的衍生變化。全部的STL容器都附帶有本身專屬的迭代器。原生指針也是一種迭代器。工具

仿函數(functor):行爲相似函數可做爲算法的某種策略。通常函數指針可認爲是俠義的仿函數。測試

配接器(adapter):一種用來修飾容器,或仿函數,或迭代器接口的東西。this

配置器(allocators)負責空間配置與管理。配置器是一個實現了動態空間配置、空間管理、空間釋放的class template。spa

由於下面主要是實現Vector的簡單操做,因此就再多講一點它。Vector是動態空間,隨着元素的加入,它的內部機制會自行擴充空間以容納新元素。所以Vector的運用對於內存的合理運用與運用得靈活性有很大的幫助。Vector維護的是一個連續的空間,不管元素的型別爲什麼,普通指針均可以做爲Vector的迭代器而知足全部必要條件。指針

Vector 的簡單實現:code

  1 #pragma once
  2 #include<iostream>
  3 #include<assert.h>
  4 #include<stdlib.h>
  5 using namespace std;
  6 template<class T>
  7 class Vector 8 { 9 public: 10 typedef T* Iterator; 11 typedef const T* Citerator; 12 public: 13  Vector() 14  :start(NULL) 15  ,finish(NULL) 16  ,endofstorage(NULL) 17  {} 18 Vector(const Vector<T>& v) 19 //:start(new T[v.endofstorage - v.start]) 20 //, finish(v.finish ) 21 //, endofstorage(v.endofstorage) 22 :start(new T[v.endofstorage - v.start]) 23 , finish(start + (v.finish - v.start)) 24 ,endofstorage(start + (v.endofstorage - v.start)) { 25 my_memcopy(start, v.start, sizeof(T)*(v.endofstorage - v.start)); 26  } 27 //向Vector中存入size個元素 28  Vector(Citerator array, size_t size) 29 :start(new T[size]) 30  , finish(start) 31 , endofstorage(start + size) { 32 for (size_t index = 0; index < size; ++size) { 33 start[index] = array[index];
finish++; 34 } 35 } 36 Vector<T>&operator=(const Vector<T>& v) { 37 if (this != &v) { 38 Vector<int>tmp(v); 39 swap(tmp); 40 } 41 return *this; 42 } 43 ~Vector(){ 44 if (start) { 45 delete[] start; 46 start = NULL; 47 // delete[] finish; 48 finish = NULL; 49 // delete[] endofstorage; 50 endofstorage = NULL; 51 } 52 } 53 // 返回首元素的迭代器 54 Iterator Begin() { 55 return start; 56 } 57 Citerator Begin()const { 58 return start; 59 } 60 // 獲取Vector中最後一個元素的下一個位置 61 Iterator End() { 62 return finish: 63 } 64 Iterator End()const { 65 return finish; 66 } 67 size_t Size()const { 68 return finish - start; 69 } 70 size_t Capacity()const { 71 return endofstorage - start; 72 } 73 bool Empty()const { 74 return finish == start; 75 } 76 T& operator[](size_t index) { 77 return start[index]; 78 } 79 const T& operator[](size_t index)const { 80 return start[index]; 81 } 82 T& At(size_t index) { 83 if ((index <= Size()) && (index >= 0)) 84 return start[index]; 85 } 86 const T& At(size_t index)const { 87 if ((index <= Size()) && (index >= 0)) 88 return start[index]; 89 } 90 // 獲取Vector中的第一個元素 91 T& Front() { 92 return srart[0]; 93 } 94 const T& Front()const { 95 return start[0]; 96 } 97 // 獲取Vector中的最後一個元素 98 T& Back() { 99 return start[finish - start]; 100 } 101 const T& Back()const { 102 return start[finish - start]; 103 } 104 void PushBack(const T& x) { 105 capacity(); 106 // start[finish - start + 1] = x; 107 start[finish - start] = x; 108 finish++; 109 } 110 void PopBack() { 111 if (!Empty()) { 112 finish--; 113 } 114 } 115 // 在pos位置上插入元素x 116 Iterator Insert(Iterator pos, const T& x) { 117 for (size_t index = Size(); index >= (size_t)(pos - start); index--) { 118 start[index + 1] = start[index]; 119 } 120 *pos = x; 121 finish++; 122 return pos; 123 } 124 // 刪除pos位置上面的元素 125 Iterator Erase(Iterator pos) { 126 for (size_t index = (size_t)(pos - start); index < Size(); index++) { 127 start[index] = start[index + 1]; 128 } 129 finish--; 130 return pos; 131 } 132 // 給Vector賦值n個值爲x的元素 133 void Assign(size_t n, const T& x) { 134 if (n > endofstorage - start) { 135 finish = start + n; 136 capacity(); 137 for (size_t index = 0; index < n; index++) { 138 start[index] = x; 139 } 140 } 141 else { 142 for (size_t index = 0; index < n; index++) 143 start[index] = x; 144 } 145 finish = start + n; 146 } 147 public:
//本身管理 擴容 148 void capacity() { 149 if (finish >= endofstorage) { 150 size_t capacity = 2 * (endofstorage - start) + 3; 151 Iterator tmp = new T[capacity];
// 拷貝元素 152 my_memcopy(tmp, start, sizeof(T)*(endofstorage - start));
154 size_t ret = finish-start; 155 delete start; 156 start = tmp; 157 finish = start + ret; 158 endofstorage = start + capacity;
//

/*Iterator pos = start;
size_t index = 0;
while (pos < endofstprage)
temp[index++] = *pos++;
deleta[] start;
start = temp;
finish = start + index;
endofstorage = start + capacity;*/

159         }
160  } 161 void swap(Vector<T>& v) { 162  std::swap(start, v.start); 163  std::swap(finish, v.finish); 164  std::swap(endofstorage, v.endofstorage); 165  } 166 void Print() { 167 for (size_t i = 0; i < Size(); i++) 168  { 169 cout << start[i] << " "; 170  } 171 cout << endl; 172  } 173 void* my_memcopy(void* dest, const void* src, size_t sz) { 174 //assert(!dest || !src); 175 assert(dest != NULL || src != NULL); 176 char* ret = (char*)dest; 177 char* tmp = (char*)src; 178 while (sz--) { 179 *ret = *tmp; 180 ret++; 181 tmp++; 182  } 183 return dest; 184  } 185 private: 186  Iterator start; 187  Iterator finish; 188  Iterator endofstorage; 189 };

之中,註釋掉的代碼部分是我曾經踩過的坑,下面是部分測試代碼

 1 #include"vector.h"
 2 void Test1()
 3 { 4 Vector<int> list1; 5 list1.PushBack(1); 6 list1.PushBack(2); 7 list1.PushBack(3); 8 list1.PushBack(4); 9 list1.PushBack(5); 10  list1.Print(); 11 Vector<int> list2; 12 list2.PushBack(0); 13 list2.PushBack(9); 14 list2.PushBack(8); 15 list2.PushBack(7); 16 list2.PushBack(6); 17  list2.Print(); 18 list1 = list2; 19  list1.Print(); 20 } 21 void Test2() 22 { 23 Vector<int> list1; 24 list1.PushBack(1); 25 list1.PushBack(2); 26 list1.PushBack(3); 27 list1.PushBack(4); 28 list1.PushBack(5); 29  list1.Print(); 30  list1.PopBack(); 31  list1.Print(); 32 list1.Insert(&list1.At(2), 0); 33  list1.Print(); 34 list1.Erase(&list1.At(3)); 35  list1.Print(); 36 } 37 int main() 38 { 39  Test1(); 40  Test2(); 41  getchar(); 42 return 0; 43 }

注意:擴容時函數中my_memcpy()函數,它的本質就是值拷貝,當Vector中存放的內置類型時沒有任何問題,可是像String類這種問題就沒法解決。因此下面給出了另外一種寫法。

/*Iterator pos = start;size_t index = 0;while (pos < endofstprage)temp[index++] = *pos++;deleta[] start;start = temp;finish = start + index;endofstorage = start + capacity;*/

相關文章
相關標籤/搜索