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