一、容器vector
1、vector结构
template <class T,class Alloc=alloc>
class vector{
public:
typedef T value_type;
typedef value_type* iterator;
typedef value_type& reference;
typedef size_t size_type;
protected:
iterator start;
iterator finish;
iterator end_of_storage;
public:
iterator begin(){return start;}
iterator end() {return finish;}
size_type size() const {return size_type(end()-begin());}
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);}
};
2、两倍增长
void push_back(const T& x){
if(finish!=end_of_storage){
construct(finish,x);
++finish;
}
else
insert_aux(end(),x);
}
template <class T,class Alloc=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;
try{
new_finish=uninitialized_copy(start,position,new start);
construct(new_finisgh,x);
++new_finish;
new_finish=uninitialized_copy(position,finish,new_finish);
}
catch(...){
destory(new_start,new_finish);
data_allocator::deallocate(new_start,len);
throw;
}
destory(begin(),end());
deallocate();
start=new_start;
finish=new_finish;
end_of_storage=new_start+len;
}
};
3、vector的迭代器iterator
template<class T,class Alloc=alloc>
class vector{
typedef T value_type;
typedef value_type* iterator;
...
};
vector<int> vec;
vector<int>::iterator ite=vec.begin():
- vector<_Tp>的大小即其父类_Vector_base<_Tp>的大小;
- 父类_Vector_base<_Tp>的大小取决于成员_Vector_impl数据类型_M_impl的大小,即类_Vector_impl<_Tp>的大小
- 类_Vector_impl<_Tp>有三个指针,3*4=12,加上父类std::allocator<_Tp>的大小(0)=12
template<typename _Tp,typename _Alloc=std::allocator<_Tp>>
class vector:protected _Vector_base<_Tp,_Alloc>
{
...
typedef _Vector_base<_Tp,_Alloc> _Base;
typedef typename _Base::pointer pointer;
typedef _gnu_cxx::_normal_iterator<pointer,vector> iterator;
};
using std::iterator_traits;
using std::iterator;
template<typename _Iterator,typename _Container>
class _normal_iterator
{
protected:
_Iterator _M_current;
typedef iterator_traits<_Iterator> _traits_type;
public:
typedef _Iterator iterator_type;
typedef typename__traits_type::iterator_category iterator_category;
typedef typename__traits_type::value_type value_type;
typedef typename__traits_type::difference_type difference_type;
typedef typename__traits_type::reference reference;
typedef typename__traits_type::pointer pointer;
template<typename _Tp,typename _Alloc>
struct _Vector_base
{
typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Tp>::other _Tp_alloc_type;
typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer pointer;
}
template<typename _Tp>
class allocator:public _glibcxx_base_allocator<_Tp>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
typedef _Tp value_type;
...
}