STL源码剖析之序列式容器vector

来源:互联网 发布:des算法破解 编辑:程序博客网 时间:2024/05/01 00:34

一、定义

vector底层是动态分配的数组,随着元素的增加,内部机制会自动扩充空间以容纳新的元素。

二、_Vector_base

vector继承自_Vector_base,实现对vector的内存管理功能。内部实现是通过继承空间分配基类_M_data_allocate成员变量,_M_allocate进行申请空间内存,_M_deallocate进行释放空间内存。而vector只需继承此基类,实现了组件功能的独立性。

// 空间分配的基类template <class _Tp, class _Allocator, bool _IsStatic>class _Vector_alloc_base {public:  typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type          allocator_type;//定义空间分配的返回类型  allocator_type get_allocator() const { return _M_data_allocator; }  _Vector_alloc_base(const allocator_type& __a)//构造函数    : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) //初始化内存管理器,空间为0  {}  protected:  allocator_type _M_data_allocator;//定义内存管理器  _Tp* _M_start;                 //空间起始位置  _Tp* _M_finish;                //空间结束位置  _Tp* _M_end_of_storage;        //可用空间结束位置  _Tp* _M_allocate(size_t __n)   //分配空间内存    { return _M_data_allocator.allocate(__n); }  void _M_deallocate(_Tp* __p, size_t __n)//释放空间内存    { if (__p) _M_data_allocator.deallocate(__p, __n); }};template <class _Tp, class _Alloc> class _Vector_base {public:  typedef _Alloc allocator_type;             //内嵌型获取类型  allocator_type get_allocator() const { return allocator_type(); }  _Vector_base(const _Alloc&)                   //构造函数    : _M_start(0), _M_finish(0), _M_end_of_storage(0) {}  _Vector_base(size_t __n, const _Alloc&)      //重载构造函数    : _M_start(0), _M_finish(0), _M_end_of_storage(0)   {    _M_start = _M_allocate(__n);    _M_finish = _M_start;    _M_end_of_storage = _M_start + __n;  }  ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }//析构函数protected:  _Tp* _M_start;//空间开始位置  _Tp* _M_finish;//空间结束位置  _Tp* _M_end_of_storage;//空间剩余可以结束位置  typedef simple_alloc<_Tp, _Alloc> _M_data_allocator;  _Tp* _M_allocate(size_t __n)//申请内存    { return _M_data_allocator::allocate(__n); }  void _M_deallocate(_Tp* __p, size_t __n) //释放内存    { _M_data_allocator::deallocate(__p, __n); }};


三、vector

vector继承了基类_Vector_base,就只需要管理元素的构造函数与析构函数。

template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >class vector : protected _Vector_base<_Tp, _Alloc> {  __STL_CLASS_REQUIRES(_Tp, _Assignable);private:  typedef _Vector_base<_Tp, _Alloc> _Base;//定义一个基类,用于空间管理public:                                   //定义vector所使用到的类别  typedef _Tp value_type;  typedef value_type* pointer;  typedef const value_type* const_pointer;  typedef value_type* iterator;           //由此可见iterator为_Tp*  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;  typedef typename _Base::allocator_type allocator_type;  //内嵌方式获取类别  allocator_type get_allocator() const { return _Base::get_allocator(); }#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION  typedef reverse_iterator<const_iterator> const_reverse_iterator;  typedef reverse_iterator<iterator> reverse_iterator;#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */  typedef reverse_iterator<const_iterator, value_type, const_reference,                            difference_type>  const_reverse_iterator;  typedef reverse_iterator<iterator, value_type, reference, difference_type>          reverse_iterator;#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */protected:#ifdef __STL_HAS_NAMESPACES  using _Base::_M_allocate;  using _Base::_M_deallocate;  using _Base::_M_start;  using _Base::_M_finish;  using _Base::_M_end_of_storage;#endif /* __STL_HAS_NAMESPACES */protected:  void _M_insert_aux(iterator __position, const _Tp& __x);  void _M_insert_aux(iterator __position);public:  iterator begin() { return _M_start; }            //获取第一个位置  const_iterator begin() const { return _M_start; }  iterator end() { return _M_finish; }            //获取最后元素标志位  const_iterator end() const { return _M_finish; }  reverse_iterator rbegin()                    //反向迭代的第一个位置    { return reverse_iterator(end()); }  const_reverse_iterator rbegin() const     { return const_reverse_iterator(end()); }  reverse_iterator rend()                        //反向迭代最后元素的标志位    { return reverse_iterator(begin()); }  const_reverse_iterator rend() const    { return const_reverse_iterator(begin()); }  size_type size() const                     //获取元素个数    { return size_type(end() - begin()); }  size_type max_size() const                      { return size_type(-1) / sizeof(_Tp); }  size_type capacity() const                //获取存储容量    { return size_type(_M_end_of_storage - begin()); }  bool empty() const                       //判断是否为空    { return begin() == end(); }  reference operator[](size_type __n) { return *(begin() + __n); } //运算符[]的重载  const_reference operator[](size_type __n) const { return *(begin() + __n); }#ifdef __STL_THROW_RANGE_ERRORS  void _M_range_check(size_type __n) const { //检查是否越界    if (__n >= this->size())      __stl_throw_range_error("vector");  //越界抛出异常  }  reference at(size_type __n)    { _M_range_check(__n); return (*this)[__n]; }  const_reference at(size_type __n) const    { _M_range_check(__n); return (*this)[__n]; }#endif /* __STL_THROW_RANGE_ERRORS */      //多种方式的构造函数  explicit vector(const allocator_type& __a = allocator_type())    : _Base(__a) {}  vector(size_type __n, const _Tp& __value,         const allocator_type& __a = allocator_type())      : _Base(__n, __a)    { _M_finish = uninitialized_fill_n(_M_start, __n, __value); }//uninitialized_fill_n,STL的全局函数,对堆上内存初始化  explicit vector(size_type __n)             : _Base(__n, allocator_type())    { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); }  vector(const vector<_Tp, _Alloc>& __x)         //拷贝构造函数    : _Base(__x.size(), __x.get_allocator())    { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); }#ifdef __STL_MEMBER_TEMPLATES  //检查是否为Integer类型  template <class _InputIterator>  vector(_InputIterator __first, _InputIterator __last,         const allocator_type& __a = allocator_type()) : _Base(__a) {    typedef typename _Is_integer<_InputIterator>::_Integral _Integral;    _M_initialize_aux(__first, __last, _Integral());  }  template <class _Integer>  void _M_initialize_aux(_Integer __n, _Integer __value, __true_type) {    _M_start = _M_allocate(__n);    _M_end_of_storage = _M_start + __n;     _M_finish = uninitialized_fill_n(_M_start, __n, __value);  }  template <class _InputIterator>  void _M_initialize_aux(_InputIterator __first, _InputIterator __last,                         __false_type) {    _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first));  }#else  vector(const _Tp* __first, const _Tp* __last,         const allocator_type& __a = allocator_type())    : _Base(__last - __first, __a)     { _M_finish = uninitialized_copy(__first, __last, _M_start); }//uninitialized_copy会依次调用拷贝构造函数#endif /* __STL_MEMBER_TEMPLATES */  ~vector() { destroy(_M_start, _M_finish); }//析构函数  vector<_Tp, _Alloc>& operator=(const vector<_Tp, _Alloc>& __x);//赋值拷贝函数  void reserve(size_type __n) {  //预留一定空间,避免内存重复及大量数据转移    if (capacity() < __n) {      const size_type __old_size = size();      iterator __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish);//重新分空间并copy      destroy(_M_start, _M_finish);          _M_deallocate(_M_start, _M_end_of_storage - _M_start);//释放原来资源      _M_start = __tmp;               //重新指定状态      _M_finish = __tmp + __old_size;      _M_end_of_storage = _M_start + __n;    }  }  reference front() { return *begin(); }  //访问第一个元素  const_reference front() const { return *begin(); }  reference back() { return *(end() - 1); }//访问最后一个元素  const_reference back() const { return *(end() - 1); }  void push_back(const _Tp& __x) {   //增加元素    if (_M_finish != _M_end_of_storage) {//是否还有可用空间      construct(_M_finish, __x);//在可用空间插入元素      ++_M_finish;               //调整状态    }    else      _M_insert_aux(end(), __x);  }  void push_back() {      if (_M_finish != _M_end_of_storage) {      construct(_M_finish);      ++_M_finish;    }    else      _M_insert_aux(end());  }  void swap(vector<_Tp, _Alloc>& __x) {//交换两个vector,交换其内部指针    __STD::swap(_M_start, __x._M_start);    __STD::swap(_M_finish, __x._M_finish);    __STD::swap(_M_end_of_storage, __x._M_end_of_storage);  }  iterator insert(iterator __position, const _Tp& __x) {//指定位置插入元素    size_type __n = __position - begin();    if (_M_finish != _M_end_of_storage && __position == end()) {      construct(_M_finish, __x);      ++_M_finish;    }    else      _M_insert_aux(__position, __x);    return begin() + __n;  }  iterator insert(iterator __position) {//获取指定位置    size_type __n = __position - begin();    if (_M_finish != _M_end_of_storage && __position == end()) {      construct(_M_finish);      ++_M_finish;    }    else      _M_insert_aux(__position);    return begin() + __n;  }  void insert (iterator __pos, size_type __n, const _Tp& __x)    { _M_fill_insert(__pos, __n, __x); }  void _M_fill_insert (iterator __pos, size_type __n, const _Tp& __x);  void pop_back() {//删除元素    --_M_finish;    destroy(_M_finish);  }  iterator erase(iterator __position) {//删除指定位置元素    if (__position + 1 != end())      copy(__position + 1, _M_finish, __position);//copy全局函数,数据的移动    --_M_finish;    destroy(_M_finish);    return __position;//返回该位置  }  iterator erase(iterator __first, iterator __last) {//删除某区间元素    iterator __i = copy(__last, _M_finish, __first);    destroy(__i, _M_finish);    _M_finish = _M_finish - (__last - __first);    return __first;  }  void resize(size_type __new_size, const _Tp& __x) {//调整内存空间    if (__new_size < size())       erase(begin() + __new_size, end());    else      insert(end(), __new_size - size(), __x);  }  void resize(size_type __new_size) { resize(__new_size, _Tp()); }  void clear() { erase(begin(), end()); } //清除vector};template <class _Tp, class _Alloc>inline bool operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)//运算符==的重载{  return __x.size() == __y.size() &&         equal(__x.begin(), __x.end(), __y.begin());}template <class _Tp, class _Alloc>inline bool operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)//运算符<的重载{  return lexicographical_compare(__x.begin(), __x.end(),                                  __y.begin(), __y.end());}template <class _Tp, class _Alloc>vector<_Tp,_Alloc>& vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x)//运算符=的重载{  if (&__x != this) {    const size_type __xlen = __x.size();    if (__xlen > capacity()) {      iterator __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end());      destroy(_M_start, _M_finish);      _M_deallocate(_M_start, _M_end_of_storage - _M_start);      _M_start = __tmp;      _M_end_of_storage = _M_start + __xlen;    }    else if (size() >= __xlen) {      iterator __i = copy(__x.begin(), __x.end(), begin());      destroy(__i, _M_finish);    }    else {      copy(__x.begin(), __x.begin() + size(), _M_start);      uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish);    }    _M_finish = _M_start + __xlen;  }  return *this;}template <class _Tp, class _Alloc>void vector<_Tp, _Alloc>::_M_fill_assign(size_t __n, const value_type& __val) {  if (__n > capacity()) {//需要大小大于空间大小    vector<_Tp, _Alloc> __tmp(__n, __val, get_allocator());//重新构造一个容器    __tmp.swap(*this);//交换容器  }  else if (__n > size()) {    fill(begin(), end(), __val);    _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val);  }  else    erase(fill_n(begin(), __n, __val), end());}#ifdef __STL_MEMBER_TEMPLATEStemplate <class _Tp, class _Alloc> template <class _InputIter>void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last,                                        input_iterator_tag) {  iterator __cur = begin();  for ( ; __first != __last && __cur != end(); ++__cur, ++__first)    *__cur = *__first;  if (__first == __last)    erase(__cur, end());  else    insert(end(), __first, __last);}template <class _Tp, class _Alloc> template <class _ForwardIter>voidvector<_Tp, _Alloc>::_M_assign_aux(_ForwardIter __first, _ForwardIter __last,                                   forward_iterator_tag) {  size_type __len = 0;  distance(__first, __last, __len);  if (__len > capacity()) {    iterator __tmp = _M_allocate_and_copy(__len, __first, __last);    destroy(_M_start, _M_finish);    _M_deallocate(_M_start, _M_end_of_storage - _M_start);    _M_start = __tmp;    _M_end_of_storage = _M_finish = _M_start + __len;  }  else if (size() >= __len) {    iterator __new_finish = copy(__first, __last, _M_start);    destroy(__new_finish, _M_finish);    _M_finish = __new_finish;  }  else {    _ForwardIter __mid = __first;    advance(__mid, size());    copy(__first, __mid, _M_start);    _M_finish = uninitialized_copy(__mid, __last, _M_finish);  }}#endif /* __STL_MEMBER_TEMPLATES */template <class _Tp, class _Alloc>void vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x){  if (_M_finish != _M_end_of_storage) {//如果当前内存池还有内存    construct(_M_finish, *(_M_finish - 1));//提出一个内存空间    ++_M_finish;    _Tp __x_copy = __x;    copy_backward(__position, _M_finish - 2, _M_finish - 1);    *__position = __x_copy;  }  else {//内存池没有可用内存    const size_type __old_size = size();    const size_type __len = __old_size != 0 ? 2 * __old_size : 1;//2倍扩张内存    iterator __new_start = _M_allocate(__len);    iterator __new_finish = __new_start;    __STL_TRY {      __new_finish = uninitialized_copy(_M_start, __position, __new_start);      construct(__new_finish, __x);      ++__new_finish;      __new_finish = uninitialized_copy(__position, _M_finish, __new_finish);    }    __STL_UNWIND((destroy(__new_start,__new_finish),                   _M_deallocate(__new_start,__len)));    destroy(begin(), end());    _M_deallocate(_M_start, _M_end_of_storage - _M_start);//释放原有内存    _M_start = __new_start;    _M_finish = __new_finish;    _M_end_of_storage = __new_start + __len;  }}template <class _Tp, class _Alloc>void vector<_Tp, _Alloc>::_M_insert_aux(iterator __position){  if (_M_finish != _M_end_of_storage) {//还有可用空间    construct(_M_finish, *(_M_finish - 1));    ++_M_finish;    copy_backward(__position, _M_finish - 2, _M_finish - 1);    *__position = _Tp();  }  else {    const size_type __old_size = size();    const size_type __len = __old_size != 0 ? 2 * __old_size : 1;//扩充两倍    iterator __new_start = _M_allocate(__len);//分配内存    iterator __new_finish = __new_start;    __STL_TRY {      __new_finish = uninitialized_copy(_M_start, __position, __new_start);      construct(__new_finish);      ++__new_finish;      __new_finish = uninitialized_copy(__position, _M_finish, __new_finish);    }    __STL_UNWIND((destroy(__new_start,__new_finish),                   _M_deallocate(__new_start,__len)));    destroy(begin(), end());    _M_deallocate(_M_start, _M_end_of_storage - _M_start);    _M_start = __new_start;    _M_finish = __new_finish;    _M_end_of_storage = __new_start + __len;  }}template <class _Tp, class _Alloc>void vector<_Tp, _Alloc>::_M_fill_insert(iterator __position, size_type __n,                                          const _Tp& __x){  if (__n != 0) {    if (size_type(_M_end_of_storage - _M_finish) >= __n) {      _Tp __x_copy = __x;      const size_type __elems_after = _M_finish - __position;      iterator __old_finish = _M_finish;      if (__elems_after > __n) {        uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);        _M_finish += __n;        copy_backward(__position, __old_finish - __n, __old_finish);        fill(__position, __position + __n, __x_copy);      }      else {        uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy);        _M_finish += __n - __elems_after;        uninitialized_copy(__position, __old_finish, _M_finish);        _M_finish += __elems_after;        fill(__position, __old_finish, __x_copy);      }    }    else {      const size_type __old_size = size();              const size_type __len = __old_size + max(__old_size, __n);      iterator __new_start = _M_allocate(__len);      iterator __new_finish = __new_start;      __STL_TRY {        __new_finish = uninitialized_copy(_M_start, __position, __new_start);        __new_finish = uninitialized_fill_n(__new_finish, __n, __x);        __new_finish          = uninitialized_copy(__position, _M_finish, __new_finish);      }      __STL_UNWIND((destroy(__new_start,__new_finish),                     _M_deallocate(__new_start,__len)));      destroy(_M_start, _M_finish);      _M_deallocate(_M_start, _M_end_of_storage - _M_start);      _M_start = __new_start;      _M_finish = __new_finish;      _M_end_of_storage = __new_start + __len;    }  }}#ifdef __STL_MEMBER_TEMPLATEStemplate <class _Tp, class _Alloc> template <class _InputIterator>void vector<_Tp, _Alloc>::_M_range_insert(iterator __pos,    //插入一个区间的元素                                     _InputIterator __first,                                      _InputIterator __last,                                     input_iterator_tag){  for ( ; __first != __last; ++__first) {    __pos = insert(__pos, *__first);    ++__pos;  }}template <class _Tp, class _Alloc> template <class _ForwardIterator>void vector<_Tp, _Alloc>::_M_range_insert(iterator __position,                                     _ForwardIterator __first,                                     _ForwardIterator __last,                                     forward_iterator_tag){  if (__first != __last) {    size_type __n = 0;    distance(__first, __last, __n);    if (size_type(_M_end_of_storage - _M_finish) >= __n) {      const size_type __elems_after = _M_finish - __position;      iterator __old_finish = _M_finish;      if (__elems_after > __n) {        uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);        _M_finish += __n;        copy_backward(__position, __old_finish - __n, __old_finish);        copy(__first, __last, __position);      }      else {        _ForwardIterator __mid = __first;        advance(__mid, __elems_after);        uninitialized_copy(__mid, __last, _M_finish);        _M_finish += __n - __elems_after;        uninitialized_copy(__position, __old_finish, _M_finish);        _M_finish += __elems_after;        copy(__first, __mid, __position);      }    }    else {      const size_type __old_size = size();      const size_type __len = __old_size + max(__old_size, __n);      iterator __new_start = _M_allocate(__len);      iterator __new_finish = __new_start;      __STL_TRY {        __new_finish = uninitialized_copy(_M_start, __position, __new_start);        __new_finish = uninitialized_copy(__first, __last, __new_finish);        __new_finish          = uninitialized_copy(__position, _M_finish, __new_finish);      }      __STL_UNWIND((destroy(__new_start,__new_finish),                     _M_deallocate(__new_start,__len)));      destroy(_M_start, _M_finish);      _M_deallocate(_M_start, _M_end_of_storage - _M_start);      _M_start = __new_start;      _M_finish = __new_finish;      _M_end_of_storage = __new_start + __len;    }  }}#else /* __STL_MEMBER_TEMPLATES */template <class _Tp, class _Alloc>void vector<_Tp, _Alloc>::insert(iterator __position,                             const_iterator __first,                             const_iterator __last){  if (__first != __last) {    size_type __n = 0;    distance(__first, __last, __n);    if (size_type(_M_end_of_storage - _M_finish) >= __n) {      const size_type __elems_after = _M_finish - __position;      iterator __old_finish = _M_finish;      if (__elems_after > __n) {        uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);        _M_finish += __n;        copy_backward(__position, __old_finish - __n, __old_finish);        copy(__first, __last, __position);      }      else {        uninitialized_copy(__first + __elems_after, __last, _M_finish);        _M_finish += __n - __elems_after;        uninitialized_copy(__position, __old_finish, _M_finish);        _M_finish += __elems_after;        copy(__first, __first + __elems_after, __position);      }    }    else {      const size_type __old_size = size();      const size_type __len = __old_size + max(__old_size, __n);      iterator __new_start = _M_allocate(__len);      iterator __new_finish = __new_start;      __STL_TRY {        __new_finish = uninitialized_copy(_M_start, __position, __new_start);        __new_finish = uninitialized_copy(__first, __last, __new_finish);        __new_finish          = uninitialized_copy(__position, _M_finish, __new_finish);      }      __STL_UNWIND((destroy(__new_start,__new_finish),                    _M_deallocate(__new_start,__len)));      destroy(_M_start, _M_finish);      _M_deallocate(_M_start, _M_end_of_storage - _M_start);      _M_start = __new_start;      _M_finish = __new_finish;      _M_end_of_storage = __new_start + __len;    }  }}#endif /* __STL_MEMBER_TEMPLATES */


0 0
原创粉丝点击