vector是个序列容器,被称为动态数组,类似于C/C++中的数组,但是其空间能够动态变化。
使用只需要包含vector/vector.h头文件,但是SGI将其实现在stl_vector.h头文件。
实现如下:
首先定义了vector基类_Vector_base,主要用于两个目的,首先,_Vector_base的构造器和析构器只分配空间单不初始化,这使得异常安全更容易;其次,封装了SGI风格的配置器和STL标准风格配置器间的差异(通过条件编译实现)。
#ifdef __STL_USE_STD_ALLOCATORS
//STL标准风格
// Base class for ordinary allocators.
template <class _Tp, class _Allocator, bool _IsStatic>
class _Vector_alloc_base {
public:
typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
allocator_type;
allocator_type get_allocator() const { return _M_data_allocator; } //返回空间配置器类型
_Vector_alloc_base(const allocator_type& __a)
: _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
{}
protected:
allocator_type _M_data_allocator; //空间配置器
_Tp* _M_start; //目前使用空间的头
_Tp* _M_finish; //目前使用空间的尾
_Tp* _M_end_of_storage; //目前可用空间的尾
_Tp* _M_allocate(size_t __n) //分配空间
{ _M_data_allocator.allocate(__n); }
void _M_deallocate(_Tp* __p, size_t __n) //释放空间
{ if (__p) _M_data_allocator.deallocate(__p, __n); }
};
// Specialization for allocators that have the property that we don't
// actually have to store an allocator object.
template <class _Tp, class _Allocator> //偏特化版本,不必要定义空间配置器成员变量
class _Vector_alloc_base<_Tp, _Allocator, true> {
public:
typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
allocator_type;
allocator_type get_allocator() const { return allocator_type(); }
_Vector_alloc_base(const allocator_type&)
: _M_start(0), _M_finish(0), _M_end_of_storage(0)
{}
protected:
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
_Tp* _M_allocate(size_t __n)
{ return _Alloc_type::allocate(__n); }
void _M_deallocate(_Tp* __p, size_t __n)
{ _Alloc_type::deallocate(__p, __n);}
};
template <class _Tp, class _Alloc>
struct _Vector_base //vector基类
: public _Vector_alloc_base<_Tp, _Alloc,
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
{
typedef _Vector_alloc_base<_Tp, _Alloc,
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
_Base;
typedef typename _Base::allocator_type allocator_type;
_Vector_base(const allocator_type& __a) : _Base(__a) {}
_Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) {
_M_start = _M_allocate(__n);
_M_finish = _M_start;
_M_end_of_storage = _M_start + __n;
}
~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
};
#else /* __STL_USE_STD_ALLOCATORS */
//SGI风格
template <class _Tp, class _Alloc>
class _Vector_base {
public:
typedef _Alloc allocator_type;
allocator_type get_allocator() const { return allocator_type(); }
_Vector_base(const _Alloc&)
: _M_start(0), _M_finish(0), _M_end_of_storage(0) {}
_Vector_base(size_t __n, const _Alloc&)
: _M_start(0), _M_finish(0), _M_end_of_storage(0)
{
_M_start = _M_allocate(__n);
_M_finish = _M_start;
_M_end_of_storage = _M_start + __n;
}
~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
protected:
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
typedef simple_alloc<_Tp, _Alloc> _M_data_allocator; //SGI风格空间配置器
_Tp* _M_allocate(size_t __n)
{ return _M_data_allocator::allocate(__n); }
void _M_deallocate(_Tp* __p, size_t __n)
{ _M_data_allocator::deallocate(__p, __n); }
};
#endif /* __STL_USE_STD_ALLOCATORS */
vector容器中元素分配的是线性空间,通过三个指针
_Tp* _M_start; //指向目前使用空间的头
_Tp* _M_finish; //指向目前使用空间的尾
_Tp* _M_end_of_storage; //指向目前可用空间的尾
管理这个线性空间。
vector实现继承至vector基类_Vector_base
template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
class vector : protected _Vector_base<_Tp, _Alloc>
{
...
}
模板参数_Tp指的是vector容器中元素类型,_Alloc指的是vector中采用的空间配置器,默认的是SGI中自己实现的。
内嵌型别定义
typedef _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;
typedef typename _Base::allocator_type allocator_type; //空间配置器型别定义,加typename告诉编译器这是模板
allocator_type get_allocator() const { return _Base::get_allocator(); } //返回空间配置 器类型
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator; //反向迭代器型别定义
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
typedef reverse_iterator<const_iterator, value_type, const_reference,
difference_type> const_reverse_iterator;
typedef reverse_iterator<iterator, value_type, reference, difference_type>
reverse_iterator;
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
构造器
- 默认构造器
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()); }
调用了uninitialized_fill_n全局函数。
- 范围构造器
#ifdef __STL_MEMBER_TEMPLATES
// Check whether it's an integral type. If so, it's not an iterator.
template <class _InputIterator>
vector(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type()) : _Base(__a) {
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_initialize_aux(__first, __last, _Integral());
}