vector概述
vector与array非常类似,它们唯一的区别在于空间运用的灵活性:array是静态空间,配置之后不能改变;vector是动态空间,随着元素的加入,它的内部机制会自动扩充空间以容纳新的元素。
vector的定义
template <class T, class Alloc = alloc>
class vector {
public: //一些类型定义
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type* iterator;
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;
protected:
typedef simple_alloc<value_type, Alloc> data_allocator; //空间配置器
iterator start; //使用空间的头指针
iterator finish; //使用空间的尾指针
iterator end_of_storage; //可用空间的尾指针
//辅助插入函数
void insert_aux(iterator position, const T& x);
//释放空间的函数
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;
}
public:
//以下方法用来返回数据结构中的一些指针
iterator begin() { return start; }
const_iterator begin() const { return start; }
iterator end() { return finish; }
const_iterator end() const { return finish; }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
//有效空间的大小
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); }
const_reference operator[](size_type n) const { return *(begin() + n); }
//一些构造函数
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()); }
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;
}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
vector(InputIterator first, InputIterator last) :
start(0), finish(0), end_of_storage(0)
{
range_initialize(first, last, iterator_category(first));
}
#else /* __STL_MEMBER_TEMPLATES */
vector(const_iterator first, const_iterator last) {
size_type n = 0;
distance(first, last, n);
start = allocate_and_copy(n, first, last);
finish = start + n;
end_of_storage = finish;
}
#endif /* __STL_MEMBER_TEMPLATiES */
//析构函数
~vector() {
destroy(start, finish);
deallocate();
}
//重载操作符 =
vector<T, Alloc>& operator=(const vector<T, Alloc>& x);
}
//获取头元素的引用
reference front() { return *begin(); }
const_reference front() const { return *begin(); }
//获取末尾元素的引用
reference back() { return *(end() - 1); }
const_reference back() const { return *(end() - 1); }
//在尾部插入元素
void push_back(const T& x) {
if (finish != end_of_storage) {
construct(finish, x);
++finish;
}
else //如果荣容量已满,需要调用insert_aux来辅助插入
insert_aux(end(), x);
}
//在特定位置插入元素
iterator insert(iterator position, const T& x) {
size_type n = position - begin();
if (finish != end_of_storage && position == end()) {
construct(finish, x);
++finish;
}
else
insert_aux(position, x);
return begin() + n;
}
iterator insert(iterator position) { return insert(position, T()); }
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void insert(iterator position, InputIterator first, InputIterator last) {
range_insert(position, first, last, iterator_category(first));
}
#else /* __STL_MEMBER_TEMPLATES */
void insert(iterator position,
const_iterator first, const_iterator last);
#endif /* __STL_MEMBER_TEMPLATES */
void insert (iterator pos, size_type n, const T& x);
void insert (iterator pos, int n, const T& x) {
insert(pos, (size_type) n, x);
}
void insert (iterator pos, long n, const T& x) {
insert(pos, (size_type) n, 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;
}
//删除某个范围上的元素
iterator erase(iterator first, iterator last) {
iterator i = copy(last, finish, first);
destroy(i, finish);
finish = finish - (last - first);
return first;
}
//调整有效区域的大小,新增加的区域用x的之值来填充
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()); }
//清空元素
void clear() { erase(begin(), end()); }
protected:
//配置空间并填充指定的值
iterator allocate_and_fill(size_type n, const T& x) {
iterator result = data_allocator::allocate(n);
__STL_TRY {
uninitialized_fill_n(result, n, x);
return result;
}
__STL_UNWIND(data_allocator::deallocate(result, n));
}
//拷贝指定范围内的元素到新配置空间
template <class ForwardIterator>
iterator allocate_and_copy(size_type n,
ForwardIterator first, ForwardIterator last) {
iterator result = data_allocator::allocate(n);
__STL_TRY {
uninitialized_copy(first, last, result);
return result;
}
__STL_UNWIND(data_allocator::deallocate(result, n));
}
iterator allocate_and_copy(size_type n,
const_iterator first, const_iterator last) {
iterator result = data_allocator::allocate(n);
__STL_TRY {
uninitialized_copy(first, last, result);
return result;
}
__STL_UNWIND(data_allocator::deallocate(result, 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>
inline void swap(vector<T, Alloc>& x, vector<T, Alloc>& y) {
x.swap(y);
}
//重载 = 运算符
template <class T, class Alloc>
vector<T, Alloc>& vector<T, Alloc>::operator=(const vector<T, Alloc>& x) {
if (&x != this) {
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);
}
else {
copy(x.begin(), x.begin() + size(), start);
uninitialized_copy(x.begin() + size(), x.end(), finish);
}
finish = start + x.size();
}
return *this;
}
//辅助插入函数
template <class T, class Alloc>
void vector<T, Alloc>::insert_aux(iterator position, const T& x) {
if (finish != end_of_storage) {
construct(finish, *(finish - 1));
++finish;
T x_copy = x;
copy_backward(position, finish - 2, finish - 1);
*position = x_copy;
}
else {
const size_type old_size = size();
const size_type len = old_size != 0 ? 2 * old_size : 1;
iterator new_start = data_allocator::allocate(len);
iterator new_finish = new_start;
__STL_TRY {
new_finish = uninitialized_copy(start, position, new_start);
construct(new_finish, x);
++new_finish;
new_finish = uninitialized_copy(position, finish, new_finish);
}
catch(...) {
destroy(new_start, new_finish);
data_allocator::deallocate(new_start, len);
throw;
}
destroy(begin(), end());
deallocate();
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}
}
template <class T, class Alloc>
void vector<T, Alloc>::insert(iterator position, size_type n, const T& x) {
if (n != 0) {
if (size_type(end_of_storage - finish) >= n) {
T x_copy = x;
const size_type elems_after = finish - position;
iterator old_finish = finish;
if (elems_after > n) {
uninitialized_copy(finish - n, finish, finish);
finish += n;
copy_backward(position, old_finish - n, old_finish);
fill(position, position + n, x_copy);
}
else {
uninitialized_fill_n(finish, n - elems_after, x_copy);
finish += n - elems_after;
uninitialized_copy(position, old_finish, finish);
finish += elems_after;
fill(position, old_finish, x_copy);
}
}
else {
const size_type old_size = size();
const size_type len = old_size + max(old_size, n);
iterator new_start = data_allocator::allocate(len);
iterator new_finish = new_start;
__STL_TRY {
new_finish = uninitialized_copy(start, position, new_start);
new_finish = uninitialized_fill_n(new_finish, n, x);
new_finish = uninitialized_copy(position, finish, new_finish);
}
catch(...) {
destroy(new_start, new_finish);
data_allocator::deallocate(new_start, len);
throw;
}
destroy(start, finish);
deallocate();
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}
}
}
template <class T, class Alloc>
void vector<T, Alloc>::insert(iterator position,
const_iterator first,
const_iterator last) {
if (first != last) {
size_type n = 0;
distance(first, last, n);
if (size_type(end_of_storage - finish) >= n) {
const size_type elems_after = finish - position;
iterator old_finish = finish;
if (elems_after > n) {
uninitialized_copy(finish - n, finish, finish);
finish += n;
copy_backward(position, old_finish - n, old_finish);
copy(first, last, position);
}
else {
uninitialized_copy(first + elems_after, last, finish);
finish += n - elems_after;
uninitialized_copy(position, old_finish, finish);
finish += elems_after;
copy(first, first + elems_after, position);
}
}
else {
const size_type old_size = size();
const size_type len = old_size + max(old_size, n);
iterator new_start = data_allocator::allocate(len);
iterator new_finish = new_start;
__STL_TRY {
new_finish = uninitialized_copy(start, position, new_start);
new_finish = uninitialized_copy(first, last, new_finish);
new_finish = uninitialized_copy(position, finish, new_finish);
}
catch(...) {
destroy(new_start, new_finish);
data_allocator::deallocate(new_start, len);
throw;
}
destroy(start, finish);
deallocate();
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}
}
}
重要函数解析
allocate_and_fill(size_type n,const &T value)
allocate_and_fill(size_type n,const &T value){
通过配置器data_allocator(类成员)调用它的allocate(n)方法,类配置n个大小的空间
}
fill_initialize(size_type n,const T &value)
void fill_initialize(size_type n,const T &value){
通过调用allocate_and_fill方法
分别设定指针start,finish,end_of_storage
}
vector(size_type n,const &T value)
vector(size_type n,const &T value){
调用allocate_and_fill(n,value)
返回的结果赋值给start指针
finish指针指向start + n
end_of_storage指针指向finish
}
insert_aux(iterator position,const T& x)
void insert_aux(iterator position,const T& x){
if 还有备用空间{
//调整水位
construct(finish,*(finish - 1));
++finish;
T x_copy = x;
调用copy_backward(position,finish-2,finish-1);
*position = x_copy;
}
else 没有备用空间{
获取原空间的大小
新空间大小为:如果远空间的大小为0,新空间为1,否则新空间的大小是原空间大小的两倍
调用data_allocator的函数来配置新空间
通过uninitialized_copy函数来将原空间的内容copy到新空间
调用construct(),将x插入到末尾
finish ++
调用destory()函数析构原vector
调用deallocate函数释放内存
}
}
push_back(const T &x)
void push_back(const T &x){
if(还有剩余空间){
调用construct(finish,x)
finish ++;
}
else
通过调用insert_aux(end(),x)重新配置空间并插入
}
pop_back()
void pop_back(){
--finish ;让finish指向最后一个元素
调用全局函数destory(finish)函数来析构finish位置的元素
}