vector的简单模拟实现
由于vector支持各类容器和数据类型,还有内存池等相关部分,这里为了方便初学者学习,不涉及模板的高级知识,只使用基础的C++知识,实现简单的vector的功能
头文件概览
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| namespace xu { template <class T> class vector { public: typedef T* iterator; typedef const T* const_iterator; iterator begin(); iterator end(); const_iterator cbegin(); const_iterator cend();
vector(); vector(int n, const T& value = T()); template<class InputIterator> vector(InputIterator first, InputIterator last); vector(vector<T>& v); vector<T>& operator= (vector<T> v); ~vector(); size_t size() const; size_t capacity() const; void reserve(size_t n); void resize(size_t n, const T& value = T());
T& operator[](size_t pos); const T& operator[](size_t pos) const; void push_back(const T& x); void pop_back();
bool empty(); void swap(vector<T>& v); iterator insert(iterator pos, const T& x); iterator erase(iterator pos);
private: iterator _start = nullptr; iterator _finish = nullptr; iterator _EndOfStorage = nullptr; }; }
|
迭代器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| typedef T* iterator; typedef const T* const_iterator; iterator begin() { return _start; } iterator end() { return _finish; } const_iterator cbegin() { return _start; } const_iterator cend() { return _finish; }
|
这里使用了原生指针作为模板的迭代器,还有rbegin、rend没有实现,也相对比较简单
构造函数与析构函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| vector() {} vector(int n, const T& value = T()) { reserve(n); while (n--) push_back(T); } template<class InputIterator> vector(InputIterator first, InputIterator last) { for (auto& i = first; i < last; i++) push_back(*i); } vector(vector<T>& v) { reserve(v.capacity()); for (const auto& e : v) push_back(e); } vector<T>& operator= (vector<T> v) { swap(v); return *this; } ~vector() { delete[] _start; _start = _finish = _EndOfStorage = nullptr; }
|
- 省略了初始化列表,放在了定义的缺省值中
- 由于实现了reserve函数,极大简化了内存申请的相关操作
- 在重载=时,由于v是拷贝构造对象,其内容可以直接使用,因此直接用swap交换其内容即可
内存相关
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| size_t size() const { return _finish - _start; } size_t capacity() const { return _EndOfStorage - _start; } void reserve(size_t n) { if (n <= capacity()) return; size_t old_size = size(); T* tmp = new T[n]; for (int i = 0; i < size(); i++) { tmp[i] = _start[i]; } delete[] _start; _start = tmp; _finish = _start + old_size; _EndOfStorage = _start + n; } void resize(int n, const T& value = T()) { if (size() > n) { _finish = _start + n; return; } reserve(n); while (_finish != _start + n) { *(_finish) = T; _finish++; }
}
|
reserve中需要注意一点,在重新申请空间之后,需要注意更新变量的顺序,否则会出现 _finish 为空指针的情况,这里处理方式有两种,一是按照 _finish _start _EndOfStorage 的顺序初始化,二是先保存下原先的数据大小,在扩容后重新赋值即可
增删查改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| T& operator[](size_t pos) { return *(_start + pos); } const T& operator[](size_t pos) const { return *(_start + pos); }
void push_back(const T& x) { if (_EndOfStorage == _finish) { size_t old_size = size(); size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2; reserve(newcapacity); } (*_finish) = x; _finish++; } void pop_back() { assert(!empty()); delete[] _finish; _finish--; }
bool empty() { return size() == 0; } void swap(vector<T>& v) { std::swap(_start, v._start); std::swap(_finish, v._finish); std::swap(_EndOfStorage, v._EndOfStorage); } iterator insert(iterator pos, const T& x) { if (_EndOfStorage == _finish) { size_t len = pos - _start; reserve(capacity() + 1); pos = _start + len; } for (iterator i = _finish - 1; i != pos; i--) { *(i + 1) = *i; } *(pos) = x; _finish++; return pos;
} iterator erase(iterator pos) { assert(!empty()); while (pos != _finish) { *(pos) = *(pos + 1); pos++; } _finish--; return pos; }
|
这里需要注意insert会出现和reserve一样的问题,数据的新旧,在扩容之后,由于pos仍然指向之前内容,需要记录和 _start 的相对位置,在扩容之后恢复即可
整体代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
| #include<iostream> #include<cassert>
namespace xu { template <class T> class vector { public: typedef T* iterator; typedef const T* const_iterator; iterator begin() { return _start; } iterator end() { return _finish; } const_iterator cbegin() { return _start; } const_iterator cend() { return _finish; }
vector() {} vector(int n, const T& value = T()) { reserve(n); while (n--) push_back(T); } template<class InputIterator> vector(InputIterator first, InputIterator last) { for (auto& i = first; i < last; i++) push_back(*i); } vector(vector<T>& v) { reserve(v.capacity()); for (const auto e : v) push_back(e); } vector<T>& operator= (vector<T> v) { swap(v); return *this; } ~vector() { delete[] _start; _start = _finish = _EndOfStorage = nullptr; }
size_t size() const { return _finish - _start; } size_t capacity() const { return _EndOfStorage - _start; } void reserve(size_t n) { if (n <= capacity()) return; size_t old_size = size(); T* tmp = new T[n]; for (int i = 0; i < size(); i++) { tmp[i] = _start[i]; } delete[] _start; _start = tmp; _finish = _start + old_size; _EndOfStorage = _start + n; } void resize(int n, const T& value = T()) { if (size() > n) { _finish = _start + n; return; } reserve(n); while (_finish != _start + n) { *(_finish) = T; _finish++; } }
T& operator[](size_t pos) { return *(_start + pos); } const T& operator[](size_t pos) const { return *(_start + pos); }
void push_back(const T& x) { if (_EndOfStorage == _finish) { size_t old_size = size(); size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2; reserve(newcapacity); } (*_finish) = x; _finish++; } void pop_back() { assert(!empty()); delete[] _finish; _finish--; }
bool empty() { return size() == 0; } void swap(vector<T>& v) { std::swap(_start, v._start); std::swap(_finish, v._finish); std::swap(_EndOfStorage, v._EndOfStorage); } iterator insert(iterator pos, const T& x) { if (_EndOfStorage == _finish) { size_t len = pos - _start; reserve(capacity() + 1); pos = _start + len; } for (iterator i = _finish - 1; i != pos; i--) { *(i + 1) = *i; } *(pos) = x; _finish++; return pos;
} iterator erase(iterator pos) { assert(!empty()); while (pos != _finish) { *(pos) = *(pos + 1); pos++; } _finish--; return pos; }
private: iterator _start = nullptr; iterator _finish = nullptr; iterator _EndOfStorage = nullptr; }; }
|
==感谢支持,如果你发现文章中有任何不严谨或者需要补充的部分,欢迎在评论区指出==