手机上自己如何做网站,招聘网站排行榜2021,陕西中洋建设工程有限公司网站,wifi优化大师下载在学习过程种 #xff0c;学习看源码是很有必要的#xff0c;它可以让你更清楚的知道一些代码的细节#xff0c;你也会发现源码将效率利用到了极致#xff0c;不得不佩服写出源码的人。
下面我将配合源码来实现一个简单的vector#xff0c;下面请看源码 看源码我们首先要…在学习过程种 学习看源码是很有必要的它可以让你更清楚的知道一些代码的细节你也会发现源码将效率利用到了极致不得不佩服写出源码的人。
下面我将配合源码来实现一个简单的vector下面请看源码 看源码我们首先要看的就是成员变量我们可以看到源码中有迭代器的start、finish、end_of_storage三个成员变量然后可以看到它将一些类型进行重命名。我们可以将它理解为下面的这张图。 其次我们接下来看它的构造函数它提供了无参和带参的构造函数看到有fill_initialize这个函数不难猜一猜可能和初始化有关。这里就不将它展开说了有兴趣的可以去看看《STL源码剖析》这本书。 学习了vector可以知道resize是一个改变vector的finish
如果传入new_size比有效元素少就将后面的元素删除如果传入的new_size比有效元素多那么就在最后加上x 与resize相对应的就是reserve函数了它是改变vector的end_of_storage
如果开辟的容量大于end_of_storage,那么就开辟一个n个空间的大小然后将数据拷贝到新空间中然后将旧空间释放掉最后改变start的指向
但是这里注意一下当发生数据拷贝的时候是不能直接进行memcpy要知道vector中存放的是一个T类型如果T是string那么当发生memcpy的时候就会发生浅拷贝里面string指向的是一块释放了的空间。 接下来我们看一下insert函数
关于insert首先我们要知道当进行插入操作时就有可能触发扩容那么就有可能触发reserve函数那么就有可能空间释放的问题所以不能memmove。 所以了解了一些特殊情况就可以实现了。
template class Tclass vector{public:typedef T* iterator;typedef const T* const_iterator;vector(): start(nullptr), finish(nullptr), end_of_storage(nullptr){}vector(size_t n, const T value){push_back(value);}explicit vector(size_t n){for (int i 0; i n; i){push_back(T());}}templateclass InputIteratorvector(InputIterator first,InputIterator last){while(first ! last){push_back(*first);first;}}vector(int n, const T value T()){resize(n, value);}vector(long n, const T value T()){resize(n, value);}// v2(v1)vector(const vectorT v){reserve(v.capacity());for (auto e : v){push_back(e);}}//v2 v1vectorT operator(vectorT v){swap(v);return *this;}~vector(){if (start){delete[] start;start finish end_of_storage nullptr;}}iterator begin(){return start;}const_iterator begin() const {return start;}iterator end(){return finish;}const_iterator end() const {return finish;}size_t size() const{return finish - start;}size_t max_size() const{return size_t(-1) / sizeof(T);}bool empty() const {return start finish;}void swap(vectorT v){::swap(start, v.start);::swap(finish, v.finish);::swap(end_of_storage, v.end_of_storage);}void resize(size_t n, T val T()){// 如果n size()就开空间将val插入到后面if (n size()){reserve(n);while (finish start n){*finish val;finish;}}else{// 将有效空间变小finish start n;}}void reserve(size_t n){if (n capacity()){size_t old size();// 申请新空间T *tmp new T[n];if (start){// memcpy(tmp,start,sizeof(T)*old);// 之所以不能用memcpy是因为如果是自定义类型深拷贝的时候就会访问释放了的空间了// 当然这里可以用引用计数或者移动构造、移动赋值来搞定这个问题。for (size_t i 0; i old; i){tmp[i] start[i];}delete[] start;}start tmp;finish start old;end_of_storage start n;}}size_t capacity() const{return end_of_storage - begin();}void push_back(const T x){if (finish ! end_of_storage){*finish x;finish;}else{size_t newcapacity capacity() 0 ? 4 : 2 * capacity();reserve(newcapacity);*finish x;finish;}}void pop_back(){assert(size() 0);--finish;}iterator erase(iterator pos){assert(pos start);assert(pos finish);// 将pos之后的元素从后往前移动iterator it pos 1;while (it finish){*pos *it;it;}--finish;return pos;}iterator insert(iterator pos,const T x){assert(pos finish pos start);if(finish end_of_storage){size_t len pos - start;reserve(capacity() 0 ? 4 : 2*capacity());pos start len;}iterator end finish;while(pos end){*end *(end-1);--end;}*pos x;finish;return pos;}T operator[](size_t n){assert(n size());return *(begin() n);}const T operator[](size_t pos) const {assert(pos start);assert(pos finish);return start[pos];}private:iterator start nullptr;iterator finish nullptr;iterator end_of_storage nullptr;};