容器是很多人对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 )
原文地址:http://blog.csdn.net/kzq_qmi/article/details/46561941