1. 程式人生 > >SGISTL原始碼閱讀十 Vector容器下

SGISTL原始碼閱讀十 Vector容器下

SGISTL原始碼閱讀十 Vector容器下

前言

之前我們已經對vector進行了比較深入的學習,本文章繼續講解vector的其他相關操作


深入原始碼

pop_back
  void pop_back() {
    --finish;
    destroy(finish);
  }

pop_back的作用是將最後一個元素清除。

erase

erase操作只負責銷燬元素,而不負責釋放空間

  //清除position位置上的元素
  iterator erase(iterator position) {
  	//將元素向前移動一位
    if (position + 1 != end())
      copy(position + 1, finish, position);
    --finish;
    //銷燬最後一個元素
    destroy(finish);
    return position;
  }
  //清除迭代器first,last指向區間的元素
  iterator erase(iterator first, iterator last) {
    //將[last,finish)上的元素拷貝到從first開始的位置上去,並返回末尾的迭代器
    iterator i = copy(last, finish, first);
    //銷燬[i, finish)的元素
    destroy(i, finish);
    //維護vector的迭代器
    finish = finish - (last - first);
    return first;
  }
clear
//清除vector中的所有元素,但是不釋放空間
void clear() { erase(begin(), end()); }

我們可以看到clear函式只是簡單地呼叫了erase函式。

resize
//傳入new_size和初始化值
void resize(size_type new_size, const T& 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, T()); }
reserve
void reserve(size_type n) {
  if (capacity() < n) {
    const size_type old_size = size();
    //分配n大小的空間,將原來的元素拷貝過去
    iterator tmp = allocate_and_copy(n, start, finish);
    //刪除原空間的元素
    destroy(start, finish);
    //釋放原空間
    deallocate();
    //調整迭代器
    start = tmp;
    finish = tmp + old_size;
    end_of_storage = start + n;
  }
}
操作符過載
//過載==
template <class T, class Alloc>
inline bool operator==(const vector<T, Alloc>& x, const vector<T, Alloc>& y) {
  //元素個數相等,三個迭代器指向的位置相同才算相等
  return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
}
//過載<
template <class T, class Alloc>
inline bool operator<(const vector<T, Alloc>& x, const vector<T, Alloc>& y) {
  return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
//...

//過載=
template <class T, class Alloc>
vector<T, Alloc>& vector<T, Alloc>::operator=(const vector<T, Alloc>& x) {
  //如果是對它本身賦值則直接返回*this
  if (&x != this) {
    /* 判斷自身的容量大小是否能存入x
     * 如果不能,分配一個跟x大小相同的空間,並將x拷貝進去
     * 然後銷燬原空間
     * 再把迭代器指向新的空間
     */
    if (x.size() > capacity()) {
      iterator tmp = allocate_and_copy(x.end() - x.begin(),
                                       x.begin(), x.end());
      destroy(start, finish);
      deallocate();
      start = tmp;
      end_of_storage = start + (x.end() - x.begin());
    }
    /* 現有元素足夠容下x
     * 直接將x的元素拷貝過來
     * 將沒有被覆蓋的元素析構掉
     */
    else if (size() >= x.size()) {
      iterator i = copy(x.begin(), x.end(), begin());
      destroy(i, finish);
    }
    /* 這種情況是現有元素的個數容不下x
     * 但是總容量可以容下x
     * 所以就需要把現有的元素全部覆蓋了,然後把x剩下的元素拷貝到未使用的空間中去
     */
    else {
      copy(x.begin(), x.begin() + size(), start);
      uninitialized_copy(x.begin() + size(), x.end(), finish);
    }
    finish = start + x.size();
  }
  return *this;
}

總結

本次我們介紹了vector的一些相關操作。
vector的學習就告一段落了。