您的位置:首页 > 其它

STL之vector学习笔记

2017-07-17 19:59 344 查看
参考SGI STL 及 侯捷《STL源码剖析》

stl vector 源码下载——带注释

概述

vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素。但是它不是单纯地 配置新空间->数据移动->释放旧空间,它实际配置的大小会比客户需求要大一点


定义

SGI STL的vector实现于stl_vector.h中,而不是vector.h中。


//_Alloc是空间配置器
template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
class vector : protected _Vector_base<_Tp, _Alloc>

----------

typedef _Tp value_type;   //vector的class _Tp的别名为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;

----------
#ifdef __STL_HAS_NAMESPACES
using _Base::_M_allocate;
using _Base::_M_deallocate;
using _Base::_M_start;      //表示目前使用空间的头
using _Base::_M_finish;     //表示目前使用空间的尾
using _Base::_M_end_of_storage;   //表示目前可用空间的尾
#endif /* __STL_HAS_NAMESPACES */

----------


vector的迭代器

vector维护的是一个连续线性空间,支持随机存取,所以vector提供的是Random Access Iterators


vector的数据结构

使用三个指针来指示整个空间


using _Base::_M_start;      //表示目前使用空间的头
using _Base::_M_finish;     //表示目前使用空间的尾
using _Base::_M_end_of_storage;   //表示目前可用空间的尾


vector的构造与内存管理

vector的实际可用空间将会比需要的空间大一些,一旦容量等于空间大小,将会将容量扩充两倍


//构造函数
explicit vector(const allocator_type& __a = allocator_type())
: _Base(__a) {}

vector(size_type __n, const _Tp& __value,
const allocator_type& __a = allocator_type())
: _Base(__n, __a)
{ _M_finish = uninitialized_fill_n(_M_start, __n, __value); }

explicit vector(size_type __n)
: _Base(__n, allocator_type())
{ _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); }

vector(const vector<_Tp, _Alloc>& __x)
: _Base(__x.size(), __x.get_allocator())
{ _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); }

//填充并初始化
template <class _Integer>
void _M_initialize_aux(_Integer __n, _Integer __value, __true_type) {
_M_start = _M_allocate(__n);
_M_end_of_storage = _M_start + __n;
_M_finish = uninitialized_fill_n(_M_start, __n, __value);
}




vector的元素操作

push_back

//将元素插到最末端
void push_back(const _Tp& __x) {
//还有备用空间
if (_M_finish != _M_end_of_storage) {
//在备用空间起始处构造一个元素,并以__x为其初值
construct(_M_finish, __x);
++_M_finish;    //调整最后一个值
}
else
//没有备用空间
_M_insert_aux(end(), __x);
}


insert

iterator insert(iterator __position, const _Tp& __x) {
size_type __n = __position - begin();
//如果还有备用空间并且插入位置是末端
if (_M_finish != _M_end_of_storage && __position == end()) {
construct(_M_finish, __x);  //在末尾构造一个以__x为初值的元素
++_M_finish;
}
else
_M_insert_aux(__position, __x);
return begin() + __n;
}

template <class _Tp, class _Alloc>
void
vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x)
{
//如果还有备用空间
if (_M_finish != _M_end_of_storage) {
//在备用空间起始位置构造一个元素,以vector最后一个元素的值为初值
construct(_M_finish, *(_M_finish - 1));
++_M_finish;                               //调整最末端
_Tp __x_copy = __x;
//将__position以后的元素后移
copy_backward(__position, _M_finish - 2, _M_finish - 1);
//将__x插入到__position的位置
*__position = __x_copy;
}
else {
//如果没有备用空间
const size_type __old_size = size();
//__old_size不为0,则将容量扩充为原来的两倍
const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
iterator __new_start = _M_allocate(__len);
iterator __new_finish = __new_start;
__STL_TRY {
//将_M_start到__positon的元素复制到新空间
__new_finish = uninitialized_copy(_M_start, __position, __new_start);
//在__position 处构造一个元素,以__x为初值
construct(__new_finish, __x);
++__new_finish;
//将剩下的元素复制到新空间
__new_finish = uninitialized_copy(__position, _M_finish, __new_finish);
}
//释放旧空间,并重新调整各个迭代器的值
__STL_UNWIND((destroy(__new_start,__new_finish),
_M_deallocate(__new_start,__len)));

destroy(begin(), end());
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
_M_start = __new_start;
_M_finish = __new_finish;
_M_end_of_storage = __new_start + __len;
}
}


pop_back

//将尾端元素取出
void pop_back() {
--_M_finish;
destroy(_M_finish);
}


erase

//清除某位置上的元素
iterator erase(iterator __position) {
if (__position + 1 != end())
//后续元素往前移动
copy(__position + 1, _M_finish, __position);
--_M_finish;
destroy(_M_finish);
return __position;
}

iterator erase(iterator __first, iterator __last) {
//将__last到_M_finish的所有元素移动到__first处
iterator __i = copy(__last, _M_finish, __first);
//将__i到_M_finish的所有元素清除
destroy(__i, _M_finish);
_M_finish = _M_finish - (__last - __first);
return __first;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: