关于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)
        {}

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); }
};

//  vector..........
void push_back(const _Tp& __x) {
        if (_M_finish != _M_end_of_storage) {    //  push back 的代码  如果没有达到分配内存的最后
                construct(_M_finish, __x);// 在已经分配的内存上 进行new 调用构造函数
                ++_M_finish; //   ++
        }
        else
                _M_insert_aux(end(), __x);
}

看看这个函数: 
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; // 重新分配 size *2
    iterator __new_start = _M_allocate(__len); // 重新分配的空间
    iterator __new_finish = __new_start;// 现在end 根start(begin)
    __STL_TRY {  // 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); // 将position之后的数据插入
    }
    __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;  // 更新
  }
}

push back 的函数比较简单.

Swap 函数:

  void swap(vector<_Tp, _Alloc>& __x) {
    __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);
  }

交换两个vextor  vector 只有三个变量  start end 还有 mem 这几个是很重要的变量.


  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
  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;
  }// 同上


  还有一种就是一种 向量的插入:


//  template <class _InputIterator>
  void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
    typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
    _M_insert_dispatch(__pos, __first, __last, _Integral());
  }
//
 void _M_insert_dispatch(iterator __pos,
                          _InputIterator __first, _InputIterator __last,
                          __false_type) {
    _M_range_insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first));
  }

//
template <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;
  }// 这个才是根本的代码
}

向量插入最根本是归入到一个元素的插入.

下面的这种插入是一种,元素的重复插入:

  void insert (iterator __pos, size_type __n, const _Tp& __x)
    { _M_fill_insert(__pos, __n, __x); }
template <class _Tp, class _Alloc>
void vector<_Tp, _Alloc>::_M_fill_insert(iterator __position, size_type __n,
                                         const _Tp& __x)
{
  if (__n != 0) { // 插入的元素格式不是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);  // 填充n个
      }//  先拷贝最后的n个, 为了防止数据覆盖.最后再拷贝position 后面的.
      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);  //最后大小是 当前vector的两倍或者
      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;
    }
  }
}// ^_^

template <class _RandomAccessIter, class _BidirectionalIter, class _Distance>
inline _BidirectionalIter __copy_backward(_RandomAccessIter __first,
                                          _RandomAccessIter __last,
                                          _BidirectionalIter __result,
                                          random_access_iterator_tag,
                                          _Distance*)
{
  for (_Distance __n = __last - __first; __n > 0; --__n)
    *--__result = *--__last;
  return __result;
} //

//
///
//    pop_back()
//
 void pop_back() {
    --_M_finish;   // 数量减少
    destroy(_M_finish);  //   析构
  }
template <class _Tp>
inline void destroy(_Tp* __pointer) {
  __pointer->~_Tp();   //注意inline应用.调用一下析构函数.
}


//  erase()
//
//
  iterator erase(iterator __position) {
    if (__position + 1 != end())  // 如果是最后一个的话那就不用copy了
      copy(__position + 1, _M_finish, __position); // 把后面的元素拷贝
    --_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;
  }// 拷贝

//
// resize()
//
  void resize(size_type __new_size, const _Tp& __x) {
    if (__new_size < size())  //如果后来的size 小于 原来的size, 就把后面的erase掉
      erase(begin() + __new_size, end());
    else  // 如果比原来的大,则使用擦如操作
      insert(end(), __new_size - size(), __x);
  }

void resize(size_type __new_size) { resize(__new_size, _Tp()); }  //如果参数缺省, 那么就调用缺省参数. 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章