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的学习就告一段落了。

猜你喜欢

转载自blog.csdn.net/lyn_00/article/details/83999549