1、相关
前面五个章节都是容器实现的一些基础工作,尤其是迭代器和空间配置器。这两个是实现容器最基础的,一个用来给容器分配空间,一个提供接口以便算法访问容器中的元素。
vector是动态数组,随着元素的加入内部会自动扩充空间容纳新元素,这也是vector实现的难点。vector是一个连续的线性空间,不管其内部放的是什么元素,使用普通指针均可以作为其迭代器,而vector迭代器所需要的操作,比如:*、->、++、--、+、-、+=、-+等普通指针天生有这些功能,所以vector的迭代器使用普通指针即可。但是其定义还是用之前实现的迭代器的普通接口。
vector的数据结构很简单,线性的连续空间,用两个迭代器start和finis表示连续空间中已经使用的范围,并用迭代器end_of_storage表示整块连续空间含有备用空间的尾端。vector实际配置的内存比客户需要的会多一些,以备将来扩充,这就是容量的概念。运用这三个迭代器可以很容易的实现vector的一些成员函数,比如begin(),end(),size()等等。
vector默认使用alloc,二级配置器作为其空间配置器,vector的成员函数涉及到元素的insert或push_back的会比较麻烦,一般会先判断vector是否还有备用空间,如果有,那么之间在备用空间构造元素即可,如果没有就涉及到将源空间的所有数据复制到另一块更大的空间,然后再将需要插入或push的元素加入到vector中。这里就需要注意一个问题,对vector的任何操作,一旦引起空间配置,那么指向原vector的迭代器都会失效。
2、代码
/*
* vector的实现
*/
#ifndef VECTOR_H_
#define VECTOR_H_
#include "allocator.h"
#include <initializer_list>
namespace MySTL
{
template <class _T, class _Alloc = alloc> // 默认使用 alloc 为配置器
class vector
{
public:
typedef _T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef const value_type* const_iterator;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
//注意vector的iterator是原生指针,经过iterator_traits
//得到迭代器型别是random_access_iterator_category
typedef value_type* iterator;
protected:
// vector专属空间配置器,每次配置一个元素大小
typedef simple_alloc<value_type, _Alloc> data_allocator;
// vector采用简单的线性连续空间。以两个迭代器start和end分别指向头尾,
// 并以迭代器end_of_storage指向容量尾端。容量(capacity)可能比(尾 - 头 = size)还大,
// 多余即备用空间。
iterator start;
iterator finish;
iterator end_of_storage;
//插入操作辅助函数
void insert_aux(iterator position, const _T& x);
//释放整个capacity
void deallocate()
{
if (start)
data_allocator::deallocate(start, end_of_storage - start);
}
void fill_initialize(size_type n, const _T& value)
{
start = allocate_and_fill(n, value); // 配置空间并设初值
finish = start + n; // 调整水位
end_of_storage = finish; // 调整水位
}
//以上函数为protected
public:
iterator begin() { return start; }
const_iterator begin() const { return start; }
iterator end() { return finish; }
const_iterator end() const { return finish; }
size_type size() const { return size_type(end() - begin()); }
size_type max_size() const { return size_type(-1) / sizeof(_T); } //2^32/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); }
const_reference operator[](size_type n) const { return *(begin() + n); }
//构造函数:
vector() : start(0), finish(0), end_of_storage(0) {} //空vector
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()); }
//拷贝构造函数
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;
}
template <class _InputIterator>
vector(_InputIterator first, _InputIterator last) :
start(0), finish(0), end_of_storage(0)
{
range_initialize(first, last, iterator