STL源码剖析(4):容器(vector)
来源:互联网 发布:查看淘宝店铺数据 编辑:程序博客网 时间:2024/05/29 09:06
容器是很多人对STL的第一印象,vector,stack,queue,set,map等等都是容器。
这里先介绍 STL中的序列式容器。
所谓序列式容器,其中的元素可序(ordered),但未必有序(sorted)。C++ 本身提供了一个序列式容器——数组(array),STL中还提供了向量(vector),链表(list),堆栈(stack),队列(queue),优先队列(priority queue)等,其中stack和queue只是将deque(双端队列)设限而得到的,技术上可以被归为一种配接器(adaptor)。
Vector:
vector的数据安排以及操作方式与array非常相似,两者的唯一差别在于空间的运用的灵活性。array是静态空间,一旦配置了就不能改变。vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素。因此,vector对内存的运用更加有效,更加有效。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;};
vector使用的线性连续空间,其中start是目前使用空间的头,finish是目前使用空间的为尾,end_of_storage是可使用空间的尾。为了降低空间配置时的速度成本,vector实际配置的大小可能比目前vector存储的数据所需的空间要大,以备将来的扩充。如果满载并有新元素加入,就另觅新居。
vector维护的是一个连续线性空间,所以无论其元素型别为何,普通指针都可以作为vector的迭代器。因为vector迭代器所执行的操作行为,如operator*,operator->,operator++,operator–,operator+,operator-,operator+=,operator-=,普通指针天生就具备。所以,vector提供的是Random Access Iterator。
vector若空间不够,在动态增长时,并不是在原来空间之后接续新空间,而是以原大小的两倍配置一块较大空间,然后将原内容拷贝过来。因此,对vector的任何操作,一旦引起空间的重新配置,指向原vector的所有迭代器就都失效了。
来看下vector几个常用操作的源码:
void push_back(const T& x) { if (finish != end_of_storage) { //空间未满 construct(finish, x); //直接构造 ++finish; } else //空间不够 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; } void pop_back() { --finish; destroy(finish); //析构}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往后移动一个位置 *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); //复制position之前的数据 construct(new_finish, x); //插入新元素 ++new_finish; new_finish = uninitialized_copy(position, finish, new_finish); //复制position之后的数据 } destroy(begin(), end());//析构原来的元素 deallocate();//释放原来的空间 start = new_start; finish = new_finish; end_of_storage = new_start + len; }}
其中copy_backward()代码如下:
template <class BidirectionalIterator1, class BidirectionalIterator2>inline BidirectionalIterator2 __copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result) { while (first != last) *--result = *--last; return result;}
其他常见操作:
Iterators:
begin:Return iterator to beginning (public member function )
end:Return iterator to end (public member function )
Capacity:
size:Return size (public member function )
capacity:Return size of allocated storage capacity (public member function )
empty:Test whether vector is empty (public member function )
Element access:
operator[]:Access element (public member function )
at:Access element (public member function )
front:Access first element (public member function )
back:Access last element (public member function )
data:Access data (public member function )
Modifiers:
push_back:Add element at the end (public member function )
pop_back:Delete last element (public member function )
insert:Insert elements (public member function )
erase:Erase elements (public member function )
swap:Swap content (public member function )
clear:Clear content (public member function )
emplace :Construct and insert element (public member function )
emplace_back :Construct and insert element at the end (public member function )
- STL源码剖析(4):容器(vector)
- 《STL源码剖析》-序列式容器(一)vector容器
- 《STL源码剖析》-序列式容器(一)vector容器
- STL源码剖析 - 第4章 序列式容器 - vector
- STL 源码剖析序列式容器之vector(四)
- STL学习笔记之容器--vector(二)源码剖析
- STL源码剖析(4):容器(list)
- stl vector源码剖析
- STL源码剖析---vector
- STL源码剖析---vector
- STL源码剖析---vector
- STL源码剖析---vector
- STL源码剖析---vector
- STL源码剖析vector
- STL源码剖析----vector
- STL源码剖析--vector
- STL源码剖析---vector
- STL源码剖析---vector
- Java 去除非中文字符
- moqui框架介绍
- Codeforces #308 C. Vanya and Scales
- C初学者如何从内置基本数据类型进阶到抽象高级数据类型
- 技术论坛 > 详解大数据存储:哪些问题最容易出现
- STL源码剖析(4):容器(vector)
- 静心,征程
- mongoDB报错Cannot find module '../build/Release/bson'
- iOS 项目中用到的一些 iOS 开源库和第三方组件
- 关于后盾网yii框架的学习小结(10)--使用AR类的增删改查
- jQuery开发之动画二
- 传智播客PHP学科进驻上海,给华东IT圈报喜
- android触摸事件流程(一)
- android 去掉顶部状态栏