目录
本节分析vector实现删除,交换,插入,重载等操作的实现
push_back和pop_back
// 如果可用空间还有就调用对象的构造函数并使用空间的尾增加
// 没有空间就重新申请一个更大的空间, 然后进行插入
void push_back(const T& x)
{
// 如果还没有到填满整个数组, 就在数据尾部插入
if (finish != end_of_storage)
{
construct(finish, x);
++finish;
}
// 数组被填充满, 调用insert_aux必须重新寻找新的更大的连续空间, 再进行插入
else
insert_aux(end(), x);
}
// 使用空间的尾自减并调用其析构函数. 但是并没有释放内存
void pop_back()
{
--finish;
destroy(finish);
}
可以看出,push和pop也保证 了finish
始终都指向最后一个元素的后一个位置的地址
删除元素-erase&clear
void clear() { erase(begin(), end()); }
// 清除指定位置的元素. 实际就是将指定位置后面的所有元素向前移动, 最后析构掉最后一个元素
iterator erase(iterator position)
{
if (position + 1 != end())
copy(position + 1, finish, position);
--finish;
destroy(finish);
return position;
}
// 清除一个指定范围的元素, 同样将指定范围后面的所有元素向前移动, 最后析构掉整个范围的元素
// 清除的是左闭右开的区间 [ )
iterator erase(iterator first, iterator last)
{
iterator i = copy(last, finish, first);
destroy(i, finish);
finish = finish - (last - first);
return first;
}
erase是左闭右开
重载运算符
重载了[] =等运算符之后,用户能更加方便地操作迭代器,看起来就像使用数组一样
vector
之间能相互的复制主要它也重载了=
, 使相互传递更加的便利
vector<T, Alloc>& operator=(const vector<T, Alloc>& x);
template <class T, class Alloc>
vector<T, Alloc>& vector<T, Alloc>::operator=(const vector<T, Alloc>& x)
{
if (&x != this)
{
// 判断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());
}
// 数组的元素大小够大, 直接将赋值的数据内容拷贝到新数组中. 并将后面的元素析构掉
else if (size() >= x.size())
{
iterator i = copy(x.begin(), x.end(), begin());
destroy(i, finish);
}
// 数组的元素大小不够, 装不完x的数据, 但是数组本身的大小够大
else
{
// 先将x的元素填满原数据大小
copy(x.begin(), x.begin() + size(), start);
// 再将x后面的数据全部填充到后面
uninitialized_copy(x.begin() + size(), x.end(), finish);
}
finish = start + x.size();
}
return *this;
}
容器的调整
reserver
修改容器实际的大小
void reserve(size_type n)
{
// 修改的容器大小要大于原始数组大小才行
if (capacity() < n)
{
const size_type old_size = size();
// 重新拷贝数据, 并将原来的空间释放掉
iterator tmp = allocate_and_copy(n, start, finish);
destroy(start, finish);
deallocate();
// 重新修改3个迭代器位置
start = tmp;
finish = tmp + old_size;
end_of_storage = start + n;
}
}
resize
重新修改数组元素的容量. 这里是修改容纳元素的大小, 不是数组的大小
void resize(size_type new_size) { resize(new_size, T()); }
void resize(size_type new_size, const T& x)
{
// 元素大小大于了要修改的大小, 则释放掉超过的元素
if (new_size < size())
erase(begin() + new_size, end());
// 元素不够, 就从end开始到要求的大小为止都初始化x
else
insert(end(), new_size - size(), x);
}
swap交换
void swap(vector<T, Alloc>& x)
{
__STD::swap(start, x.start);
__STD::swap(finish, x.finish);
__STD::swap(end_of_storage, x.end_of_storage);
}
总结
本节将vector
的删除, 交换, 重载等操作进行的分析. 学到关于交换数组可以修改头尾指针即可, 并不实际交换整个元素. 同时要注意erase
清除是一个左闭右开的区间. 因为insert的代码很多,也有一点复杂, 所以我将插入操作放到下节进行分析