赞
踩
vector是表示可变大小数组的序列容器。 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素 进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存 储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末 尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。
vector的底层我模仿库里面的实现方法,设计了三个指针:
- class vector
- {
- public:
- typedef T* iterator;
-
- private:
-
- iterator _start; // 指向数据块的开始
-
- iterator _finish; // 指向有效数据的尾
-
- iterator _endOfStorage; // 指向存储容量的尾
- }
以及正向迭代器,不可修改迭代器,各种构造函数,析构函数, reserve(预开辟出空间,字符串还是原来的大小(一般不缩容)),resize(将vector设定为指定大小,字符串占满所开辟的空间),push_back(尾插),pop_back(尾删),insert(在pos位置上插入x,并返回pos位置的地址),erase(删除pos位置上的元素,并返回该位置的地址)。
以reserve为例,当reserve开辟新空间时会释放原来的旧空间,导致_start,_finish都不是原来的_start,_finish,如果此时贸然对_start,_finish进行运算,很可能会导致程序崩溃。我的做法是先记录下原来vector的长度,再用_start加上记录下的长度,就能得到正确的_finish,具体实现见下面代码。
- #pragma once
- #include <iostream>
- using namespace std;
-
- namespace sxb
- {
- template<class T>
-
- class vector
- {
- public:
- typedef T* iterator;
-
- private:
-
- iterator _start; // 指向数据块的开始
-
- iterator _finish; // 指向有效数据的尾
-
- iterator _endOfStorage; // 指向存储容量的尾
-
- public:
-
- // Vector的迭代器是一个原生指针
-
- typedef const T* const_iterator;
-
- iterator begin()
- {
- return _start;
- }
-
- iterator end()
- {
- return _finish;
- }
-
- const_iterator cbegin() const
- {
- return _start;
- }
-
- const_iterator cend() const
- {
- return _finish;
- }
-
- // construct and destroy
-
- vector() {}
-
- //构造一个长度为n,值为value的vector
- vector(int n, const T& value = T())
- {
- _start = new T[n+1];
- _finish = _start + n;
- _endOfStorage = _start + n;
-
- for (int i = 0; i < n; i++)
- {
- *(_start + i) = value;
- }
- }
-
- template<class InputIterator>
- //利用一段迭代器构造
- vector(InputIterator first, InputIterator last)
- {
- int len = 0;
- while (first != last)// 1 2 3 4 5
- {
- len++;
- first++;
- }
- len++;
- _start = new T[len+1];
- memcpy(_start, first, sizeof(T) * len);
- _finish = _start + len;
- _endOfStorage = _finish;
-
- }
- //利用已有的vector构造
- vector(const vector<T>& v)
- {
- _start = new T[v.size() + 1];
- memcpy(_start, v.cbegin(), sizeof(T) * v.size());
- _finish = _start + v.size();
- _endOfStorage = _finish;
- }
- //赋值构造
- vector<T>& operator= (vector<T> v)
- {
- vector(v);
-
- return *this;
- }
-
- ~vector()
- {
- delete[] _start;
- _finish = nullptr;
- _endOfStorage = nullptr;
- }
-
- // capacity
-
- size_t size() const
- {
- return _finish - _start;
- }
-
- size_t capacity() const
- {
- return _endOfStorage - _start;
- }
-
- void reserve(size_t n)
- {
- if (n > capacity())
- {
- T* tmp = new T[n + 1];
- //迭代器失效处理
- int oldnum = _finish - _start;
- memcpy(tmp, _start, sizeof(T) * (_finish - _start));
- delete[] _start;
- _start = tmp;
- _finish = _start + oldnum;
- _endOfStorage = _start + n;
- }
- }
-
- void resize(size_t n, const T& value = T())
- {
- if (n > capacity())
- {
- int oldnum = _finish - _start;
- reserve(n);
- while ((_start + oldnum) != _endOfStorage)
- {
- *(_start + oldnum) = value;
- oldnum++;
- }
- }
- else
- {
- _finish = _start + n;
- }
- }
-
-
-
- ///access///
-
- T& operator[](size_t pos)
- {
- return *(_start + pos);
- }
-
- const T& operator[](size_t pos)const
- {
- return *(_start + pos);
- }
-
-
-
- ///modify/
-
- void push_back(const T& x)
- {
- if (size() == capacity())
- {
- reserve(capacity() == 0 ? 4 : capacity() * 2);
- }
- _start[size()] = x;
- _finish++;
- }
-
- void pop_back()
- {
- _finish--;
- }
-
- 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)
- {
- int len = 0;
- while (pos != _start)
- {
- len++;
- pos--;
- }
- if (size() == capacity())
- {
- reserve(capacity() == 0 ? 4 : capacity() * 2);
- }
- iterator endfinish = _finish;
- while (endfinish > _start + len)
- {
- *(endfinish) = *(endfinish - 1);
- endfinish--;
- }
- *endfinish = x;
- _finish++;
-
- return _start + len;
- }
-
- iterator erase(iterator pos)
- {
- iterator pos2 = pos;
- while (pos != _finish - 1)
- {
- *pos = *(pos + 1);
- pos++;
- }
- _finish--;
- return pos2;
- }
- };
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。