關於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()); }  //如果參數缺省, 那麼就調用缺省參數. 

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