Vector是序列容器的一种,分配的是一段连续的空间,所以它支持下标访问,同时它另一特点是可以自行扩充空间,每次是以原大小两倍来扩充,是另外配置的一块空间,将原内容拷贝过去,所以当对vector的空间进行重新配置时,指向原vector的迭代器就失效了。下面分析它具体是怎么实现的和熟悉下vector内部函数
- 迭代器
里面主要有三个迭代器
iterator start; // 表示目前使用空间的头
iterator finish; // 表示目前使用空间的尾
iterator end_of_storage; // 表示vector可用空间的尾部
- 构造函数
vector() : start(0), finish(0), end_of_storage(0) {}
vector(size_type n, const T& value) { fill_initialize(n, value); }
vector(int n, const T& value) { fill_initialize(n, value); }
vector(long n, const T& value) { fill_initialize(n, value); }
explicit vector(size_type n) { fill_initialize(n, T()); } //加explicit防止发生隐式转换
vector(const vector<T, Alloc>& x)
{
start = allocate_and_copy(x.end() - x.begin(), x.begin(), x.end());
finish = start + (x.end() - x.begin());
end_of_storage = finish;
}
Vector有多种构造函数,可以看到它主要可以有一下几种形式构造
Vector<int> ss(10,0)
Vector<int> ss(10)
Vector<int> ss(s) //拷贝构造,s是已初始化的vector对象
可以看到空间申请主要是用的fill_initialize函数
void fill_initialize(size_type n, const T& value) {
start = allocate_and_fill(n, value);
finish = start + n;
end_of_storage = finish;
}
可以看到它主要是调用了allocate_and_fill申请空间
iterator allocate_and_fill(size_type n, const T& x) {
__STL_TRY {
uninitialized_fill_n(result, n, x); //初始化allocate分配的未初始化空间
return result;
}
__STL_UNWIND(data_allocator::deallocate(result, n)); //失败回收空间
}
3.一些特殊操作函数
iterator begin() { return start; } //获取相应迭代器
iterator end() { return finish; }
// 返回当前对象个数
size_type size() const { return size_type(end() - begin()); }
size_type max_size() const { return size_type(-1) / sizeof(T); }
size_type capacity() const { return size_type(end_of_storage - begin()); }
bool empty() const { return begin() == end(); } //是否为空
reference operator[](size_type n) { return *(begin() + n); }
reference front() { return *begin(); } //访问元素
reference back() { return *(end() - 1); }
void push_back(const T& x)
{
if (finish != end_of_storage)
{
construct(finish, x); //,空间不满足重新分配内存空间
++finish;
}
else
insert_aux(end(), x); //直接追加元素
}
void pop_back()
{
--finish;
destroy(finish);
}
iterator erase(iterator position)
{
if (position + 1 != end())
copy(position + 1, finish, position);
--finish;
destroy(finish);
return position;
}