欢迎来到我的Blog,点击关注哦💕
string的特性和用法以及底层的探索已经,虽然string不算container的成员之一,但是也见到了其的影子,接下来让我们看看vector
vector 是 C++ 标准模板库(STL)中的一个动态数组容器,它提供了动态大小调整和高效的随机访问功能。vector 的元素在内存中是连续存储的,这意味着可以通过指针或索引高效地访问元素。vector 自动管理其内部使用的内存,不需要手动分配和释放,支持常见容器操作,如插入、删除、遍历等.
| (constructor)构造函数声明 | 接口说明 |
|---|---|
| vector(size_type n, const value_type& val = value_type()) | 构造并初始化n个val |
| vector (const vector& x); (重点) | 拷贝构造 |
| vector (InputIterator first, InputIterator last); | 使用迭代器进行初始化构造 |
| 函数声明 | 接口说明 |
|---|---|
| begin + end | 返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器 |
| rbegin + rend | 返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的 reverse_iterator,即begin位置 |
| 函数声明 | 接口说明 |
|---|---|
| capacity | 获取容量大小 |
| size | size 获取数据个数 |
| empty | 判断是否为空 |
| resize | 改变vector的size |
| reserve | 改变vector的capacity |
| vector增删查改 | 接口说明 |
|---|---|
| push_back(重点) | 尾插 |
| pop_back (重点) | 尾删 |
| find | 查找。(注意这个是算法模块实现,不是vector的成员接口) |
| insert | 在position之前插入val |
| erase | 删除position位置的数据 |
| swap | 交换两个vector的数据空间 |
| operator[] | 像数组一样访问 |
vector模拟实现结构上使用命名空间myvector进行封装,防止与库冲突,使用class封装成为对象vector
这样typedef的一点是和STL保持一致
vector写成类模板,可以支持存贮多种类型数据_start表示数据存储的开始地址_finish表示数据存贮的的下一个地址_end_of_storage表示数据当前开辟的最大空间的地址namespace myvector { template class vector { public: typedef T* iterator; typedef const T* const_iterator; private: iterator _start; iterator _finish; iterator _end_of_storage; }; } vector() :_start(nullptr) , _finish(nullptr) , _end_of_storage(nullptr) {} n个val初始化对象vector(size_t n, const T& val = T()) { resize(n, val); } template vector(InputIterator first, InputIterator last) { while (first != last) { push_back(*first); ++first; } } new出和传递的对象一样大小的空间,在string类中我们利用了mencpy进行拷贝,在vector中不采用mencpymencpy拷贝只能进行内置类型的浅拷贝,不能进行自定义类型的深拷贝push_back_finish和_end_of_storage的初始化vector(const vector& v) { _start = new T[v.capacity()]; for (size_t i = 0; i < v.size(); i++) { _start[i] = v._start[i]; } _finish = _start + v.size(); _end_of_storage = _start + v.capacity(); } operator=的参数中是值传递,是实参的拷贝,这里面利用这个特性进数据的交换this指针就是赋值的内容了void swap(vector v) { std::swap(_start, v._start); std::swap(_finish, v._finish); std::swap(_end_of_storage, v._end_of_storage); } vector operator=(vector v) { swap(v); return *this; } _start是否为空为空,避免再次析构~vector() { if (_start) { delete[] _start; _start = _finish = _end_of_storage = nullptr; } } size和capzcityvector的size和capacity不同于string类中的不一样,vector定义的是指针capacity和sizesize_t size()const { return _finish - _start; } size_t capacity()const { return _end_of_storage - _start; } capacity,以避免重复扩容效率低下_start_finish_end_of_storage已经失效push_back_start_finish_end_of_storagevoid reserve(size_t n) { if (n > capacity()) { T* tmp = new T[n]; size_t sz = size(); if (_start) { //memcpy(tmp, _start, sizeof(T)*capacity()); //string 类深拷贝 for (int i = 0; i < sz; i++) { tmp [i] = _start[i]; } delete[] _start; } _start = tmp; _finish = sz + _start; _end_of_storage = _start + n; } } 两种情况
N<capacity
直接进行移动_finish
N>capacity
进行容量的检查和扩容,依次赋值val
const T& val = T()这句话是针对内置类型和自定义类型,C++这里将内置类型进行了升级
int = 1; <=> int(1);//这里int有点像构造函数 void resize(size_t n, const T& val = T()) { if (n < capacity()) { _finish = n + _start; } else { reserve(n); while (_finish != _start + n) { *_finish = val; ++_finish; } } } 首先进行容量的检查
_finsih位置解引用赋值,++_finsihvoid push_back(const T& x) { if (_finish == _end_of_storage) { size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2; reserve(newcapacity); } *_finish = x; ++_finish; } erasevoid pop_back() { erase(end()-1); } pos越界访问_finish == _end_of_storagesize_t step = pos - _start用step记录,距离 _start距离,扩容的时候将原空间释放,pos将无法访问,扩容完成后进行pos的恢复pos位置的数据依次进行移动、pos位置的值,修改_finishpositerator insert(iterator pos, const T& x) { assert(pos <= _finish && pos >= _start); if (_finish == _end_of_storage) { //防止迭代器失效 size_t step = pos - _start; size_t newcapacity = capacity() == 0 ? 0 : capacity() * 2; reserve(newcapacity); //防止迭代器失效 pos = _start + step; } iterator end = _finish - 1; while (end >= pos) { *(end + 1) = *end; ++end; } *pos = x; ++_finish; return pos } pos越界访问pos后面的元素向前面移动,进行覆盖positerator erase(iterator pos) { assert(pos <= _finish && pos >= _start); while (pos != _finish) { *pos = *(pos + 1); pos++; } --_finish; return pos } const和非const两种,只读和可读可改T& operator[](size_t pos) { assert(pos >= 0 && pos < size()); return _start[pos]; } const T& operator[](size_t pos)const { assert(pos >= 0 && pos < size()); return _start[pos]; } //iterator const_iterator cbegin() { return _finish; } const_iterator cend() const { return _start; } iterator begin() { return _start; } iterator end() { return _finish; } const_iterator begin()const { return _start; } const_iterator end()const { return _finish; #include #include #include namespace MyVector { template class vector { public: //iterator const_iterator cbegin() { return _finish; } const_iterator cend() const { return _start; } iterator begin() { return _start; } iterator end() { return _finish; } const_iterator begin()const { return _start; } const_iterator end()const { return _finish; } //默认构造 vector() :_start(nullptr) , _finish(nullptr) , _end_of_storage(nullptr) {} vector(size_t n, const T& val = T()) { resize(n, val); } ~vector() { if (_start) { delete[] _start; _start = _finish = _end_of_storage = nullptr; } } vector(const vector& v) { _start = new T[v.capacity()]; for (size_t i = 0; i < v.size(); i++) { _start[i] = v._start[i]; } _finish = _start + v.size(); _end_of_storage = _start + v.capacity(); } void swap(vector v) { std::swap(_start, v._start); std::swap(_finish, v._finish); std::swap(_end_of_storage, v._end_of_storage); } template vector(InputIterator first, InputIterator last) { while (first != last) { push_back(*first); ++first; } } vector operator=(vector v) { swap(v); return *this; } //capacity void reserve(size_t n) { if (n > capacity()) { std::cout << "reserve(size_t n)" << std::endl; T* tmp = new T[n]; size_t sz = size(); if (_start) { //memcpy(tmp, _start, sizeof(T)*capacity()); //string 类深拷贝 for (int i = 0; i < sz; i++) { tmp [i] = _start[i]; } delete[] _start; } _start = tmp; _finish = sz + _start; _end_of_storage = _start + n; } } size_t size() { return _finish - _start; } size_t capacity() { return _end_of_storage - _start; } size_t size()const { return _finish - _start; } size_t capacity()const { return _end_of_storage - _start; } //modify void push_back(const T& x) { if (_finish == _end_of_storage) { size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2; reserve(newcapacity); } *_finish = x; ++_finish; } void pop_back() { erase(end()-1); } void insert(iterator pos, const T& x) { assert(pos <= _finish && pos >= _start); if (_finish == _end_of_storage) { //防止迭代器失效 size_t step = pos - _start; size_t newcapacity = capacity() == 0 ? 0 : capacity() * 2; reserve(newcapacity); //防止迭代器失效 pos = _start + step; } iterator end = _finish - 1; while (end >= pos) { *(end + 1) = *end; ++end; } *pos = x; ++_finish; return pos; } void erase(iterator pos) { assert(pos <= _finish && pos >= _start); while (pos != _finish) { *pos = *(pos + 1); pos++; } --_finish; return pos; } void resize(size_t n, const T& val = T()) { if (n < capacity()) { _finish = n + _start; } else { reserve(n); while (_finish != _start + n) { *_finish = val; ++_finish; } } } T& operator[](size_t pos) { assert(pos >= 0 && pos < size()); return _start[pos]; } const T& operator[](size_t pos)const { assert(pos >= 0 && pos < size()); return _start[pos]; } private: iterator _start; iterator _finish; iterator _end_of_storage; }; }
上一篇:WebSocket协议测试