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;
}