1.容器的概念和分类
STL容器是将基本的数据结构实现出来。根据数据在容器中的排列,分为序列式容器和关联式容器。
SGI的各种容器如下图:
1.1 序列式容器
所谓序列式容器,其中的元素都可序(ordered),但未排序(sorted)。C++ 语言本身提供了㆒个序列式容器 array,STL 另外再提供 vector , list , deque ,stack , queue , priority-queue 等等序列式容器。其中 stack 和 queue 由于只是将 deque 改头换面而成,技术上被归类为配接器(adapter)。
2 vector
2.1 vector概述
vector可以根据需要的空间大小,动态增长空间。vector实现的关键技术,在于对大小的控制以及重新配置数据时的移动效率。
2.2 vector定义摘要
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;
//反向迭代器
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;
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);
}
2.3 vector的迭代器
vector的迭代器是一个指针
typedef value_type* iterator
2.3 vector的数据结构
vector数据结构用两个迭代器start和finishe分别指向配置来的连续空间中使用的范围,并用end_of_storage指向整块连续的区域。
iterator start; //当前使用空间的头
iterator finish; //当前使用空间的尾
iterator end_of_storage; //当前可用空间的尾
vector的扩容:实际配置比需求大一些,以免每次都要重新申请空间。
运用 start, finish, end_of_storage 三个迭代器,便可轻易提供首尾标示、大小、容量、空容器判断、注标([ ])运算子、最前端元素值、最后端元素值。
2.4 vecotr的构造和内存管理
vector使用缺省的alloc作为空间配置器,提供了很多constructors
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;
}
//用迭代器初始化
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;
}
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;
}
vector的插入操作:先检查是否有备用空间,如果有就直接在备用空间上构造函数,并调整迭代器finish;如果没有,就扩充空间(重新配置,移动数据,释放空间)
void push_back(const T& x) {
if (finish != end_of_storage) {//有备用空间
construct(finish, x);
++finish;
}
else
insert_aux(end(), x);//没有备用空间
}
//insert_aux函数的实现,在position位置插入x
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-1)元素
++finish;
T x_copy = x;
//这个函数是把[posiont,finish-2]的元素复制到[finish-1-(finish-2-posion), finish-1]
//就是一finish-1为最后一个元素,复制position到finish-2这段区域的元素。
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;//增长两倍,其中0->1
iterator new_start = data_allocator::allocate(len);申请len长度的空间
iterator new_finish = new_start;
__STL_TRY {
new_finish = uninitialized_copy(start, position, new_start);//先复制一段[start, position)
construct(new_finish, x);//再构造x
++new_finish;
new_finish = uninitialized_copy(position, finish, new_finish);//最后复制下一段[position,finish)
}
# ifdef __STL_USE_EXCEPTIONS //这个是如果构造不成功,就全部销毁
catch(...) {
destroy(new_start, new_finish);
data_allocator::deallocate(new_start, len);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
destroy(begin(), end());//释放原来的空间
deallocate();
start = new_start;//调整迭代器
finish = new_finish;
end_of_storage = new_start + len;
}
2.6 vector的元素操作:pop_back,erase,clear,insert
insert已经在2.5中说明
//弹出尾部元素
void pop_back() {
--finish;
destroy(finish);
}
//删除posiont处的元素
iterator erase(iterator position) {
if (position + 1 != end())
copy(position + 1, finish, position);
--finish;
destroy(finish);
return position;
}
//删除[first,last)
iterator erase(iterator first, iterator last) {
iterator i = copy(last, finish, first);
destroy(i, finish);
finish = finish - (last - first);
return first;
}
void clear() { erase(begin(), end()); }
以上就是vector的分析