STL源码剖析(一)-vector

    xiaoxiao2021-03-25  99

    开始学习 STL源码剖析

    已经学习了前两章 有关内存管理 以及 迭代器

    下面 先尝试自己写vector再根据源代码进行 修改 以下为代码

    #ifndef _VECTOR_H #define _VECTOR_H #include "alloc.h" #define _VECTOR_OVERFLOW std::cerr<<"Vector overflow"<<std::endl; exit(1) template<class T,class Alloc = alloc> class vector { public: typedef T value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type* iterator; typedef const value_type* const_iterator; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; protected: iterator start; iterator finish; iterator end_of_storage; simple_alloc<value_type, Alloc> data_allocater; void refill() { size_type gap = finish - start; size_type old_sz = end_of_storage - start; size_type new_sz = 2 * old_sz + 1; if (!start) start = (iterator)data_allocater.allocate(new_sz); else start = (iterator)data_allocater.reallocate(start, old_sz, new_sz); finish = start + gap; end_of_storage = start + new_sz; } public: ~vector() { if (start) data_allocater.dellocate(start, (size_t)(end_of_storage - start)); } vector() : start(0),finish(0),end_of_storage(0) {} iterator begin() { return start; } iterator end() { return finish; } size_type size() const { return (size_type)(finish - start); } size_type capacity() const { return (size_type)(end_of_storage - start); } bool empty() const { return start == finish; } reference front() { return *start; } reference back() { return *(finish - 1); } void push_back(const_reference value) { if (finish == end_of_storage) refill(); *finish++ = value; } reference operator[](size_type n) { if (start + n >= finish) { _VECTOR_OVERFLOW; } return *(start + n); } void erase(iterator i) { size_type copy_sz = finish - i - 1; memcpy(i, i + 1, copy_sz * sizeof(int)); --finish; } void erase(iterator low, iterator up) { memcpy(low, up + 1, (finish - up - 1)*sizeof(value_type)); finish -= (up - low + 1); } void insert(iterator i, const_reference value) { size_type locate = i - start; if (finish == end_of_storage) refill(); memcpy(start + locate + 1, start + locate, (finish - start - locate)*sizeof(value_type)); *(start + locate) = value; ++finish; } void insert(iterator i, size_type n, const_reference value) { size_type locate = i - start; if (finish == end_of_storage) refill(); memcpy(start + locate + n, start + locate, (finish - start - locate) * sizeof(value_type)); for(size_type t=0;t<n;++t) *(start + locate + t) = value; finish += n; } void resize(size_type new_sz, const_reference value) { if (new_sz > size()) insert(finish, new_sz-size(), value); else erase(start + new_sz, finish - 1); } void resize(size_type n) { resize(n, 0); } void clear() { if(start) data_allocater.dellocate(start, (size_t)(end_of_storage - start)); start = finish = end_of_storage = 0; } }; #endif // !_VECTOR_H

    以下为 借鉴书上代码改正的 主要改了以下几点

    1. 数据的 构造 与 析构 的问题

    2. 扩充缓冲区大小计算的问题 由原来oldsize的两倍 改为了  2*(oldsize + needsize)

    3. 坚持贯彻左闭右开 将erase改正

    4. 由于没写 copy  因此 都是用的memcpy  因此 拷贝时 也没有构造析构的过程

    #ifndef _WVECTOR_H #define _WVECTOR_H #include "alloc.h" #include "stl_construct.h" #define _VECTOR_OVERFLOW std::cerr<<"Vector overflow"<<std::endl; exit(1) template<class T, class Alloc = alloc> class vector { public: typedef T value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type* iterator; typedef const value_type* const_iterator; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; protected: iterator start; iterator finish; iterator end_of_storage; simple_alloc<value_type, Alloc> data_allocater; void refill(size_type need_sz) { size_type gap = finish - start; size_type old_sz = end_of_storage - start; size_type new_sz = 2 * (old_sz + need_sz); if (!start) start = (iterator)data_allocater.allocate(new_sz); else start = (iterator)data_allocater.reallocate(start, old_sz, new_sz); finish = start + gap; end_of_storage = start + new_sz; } void dellocate() { if (start) data_allocater.dellocate(start, (size_t)(end_of_storage - start)); } public: ~vector() { destroy(start, finish); dellocate(); } vector() : start(0), finish(0), end_of_storage(0) {} iterator begin() { return start; } iterator end() { return finish; } size_type size() const { return (size_type)(finish - start); } size_type capacity() const { return (size_type)(end_of_storage - start); } bool empty() const { return start == finish; } reference front() { return *start; } reference back() { return *(finish - 1); } void push_back(const_reference value) { if (finish == end_of_storage) refill(1); construct(finish++, value); } reference operator[](size_type n) { if (start + n >= finish) { _VECTOR_OVERFLOW; } return *(start + n); } void erase(iterator i) { size_type copy_sz = finish - i - 1; if(copy_sz) memcpy(i, i + 1, copy_sz * sizeof(int)); destroy(--finish); } void erase(iterator low, iterator up) { memcpy(low, up, (finish - up) * sizeof(value_type)); destroy(finish - (up - low), finish); finish -= (up - low); } void insert(iterator i, const_reference value) { size_type locate = i - start; if (finish == end_of_storage) refill(1); memcpy(start + locate + 1, start + locate, (finish - start - locate) * sizeof(value_type)); *(start + locate) = value; ++finish; } void insert(iterator i, size_type n, const_reference value) { size_type locate = i - start; if (finish == end_of_storage) refill(n); memcpy(start + locate + n, start + locate, (finish - start - locate) * sizeof(value_type)); for (size_type t = 0; t<n; ++t) *(start + locate + t) = value; finish += n; } void resize(size_type new_sz, const_reference value) { if (new_sz > size()) insert(finish, new_sz - size(), value); else erase(start + new_sz, finish); } void resize(size_type n) { resize(n, T()); } void clear() { destroy(start, finish); finish = start; } }; #endif // !_WVECTOR_H

    转载请注明原文地址: https://ju.6miu.com/read-17412.html

    最新回复(0)