1. 空间运用灵活性
vector与数组的唯一差别就在于空间运用的灵活性。vector的空间是可以动态增长的(但是不能减小)。需要空间运用的灵活性,vector就必须引入空间增长的机制,相应的也会有一些属性和接口。如下图:
2. vector的操作:push_back, pop_back, resize, reserve,erase, clear, insert,swap,assign
另外的一些基础常用的操作就略过了。
2.1. push_back
在元素的尾端插入,也就是finish(end()操作的返回值)所指之处。如果空间不够(finsh=end_of_storage)的话那么新开辟一块2倍于现在大小的空间,将vector复制过去后再进行插入。
2.2. pop_back
- void pop_back()
- {
- --finish;
- destroy(finish);
- }
2.3. resize
resize操作是用来改变已用空间的大小的,而不是总的分配空间的大小。
- void resize(size_type new_size, constT& x) {
- if (new_size < size())
- erase(begin() + new_size, end());
- else
- insert(end(), new_size - size(), x);
- }
- void resize(size_typenew_size) { resize(new_size, T()); }
- // 清除全部元素。注意,并未释放空间(其实vector的空间是不可能减小的)。
2.4. reserve
- void reserve(size_typen)
- {
- if (capacity()< n) //如果capacity比n大就不会有任何操作,不要指望减小vector的空间
- {
- const size_type old_size = size();
- iterator tmp = allocate_and_copy(n, start, finish);
- destroy(start, finish);
- deallocate();
- start = tmp;
- finish = tmp + old_size;
- end_of_storage = start + n;
- }
- }
2.5. erase
- //将迭代器position所指元素移除
- iterator erase(iterator position)
- {
- if (position + 1 != end()) // 如果p 不是指向最后一个元素
- // 将p之后的元素一一前移
- copy(position + 1, finish, position);
- --finish;
- destroy(finish);
- return position;
- }
- //迭代器范围版本
- iterator erase(iterator first, iterator last)
- {
- iterator i = copy(last, finish, first);
- destroy(i,finish);
- finish = finish - (last - first);
- return first;
- }
注意erase的核心操作时copy算法。
2.6. clear
clear就是调用erase操作。
- void clear(){ erase(begin(), end()); }
2.7. insert
需要频繁调用insert的时候应该采用list,但是vector也提供insert操作。
2.8. swap
swap是所有顺序容器都提供的操作。就是交换两容器的存储内容,不过这里的交换并不是真的将存储内容交换,而是交换一些结构参数而已。
- void swap(vector<T, Alloc>& x)
- {
- __STD::swap(start, x.start);
- __STD::swap(finish, x.finish);
- __STD::swap(end_of_storage, x.end_of_storage);
- }
这样swap就很有效率了。从上面的代码来看,我搞不懂为什么Primer上说swap后迭代器不失效。
2.9. assign
assign操作也是顺序容器共有的操作,两种接口:
c.assign(b,e)——重新设置c,内容为迭代器b,e之间元素
c.assign(n,t)——重新设置c,内容为n个t
第一个接口,提供了不同容器之间的赋值,当然前提是存储的元素类型相同。比如:
- std::list<std::string> ls;
- ……..
- std::deque<std::string> de;
- de.assign(ls.begin(),ls.end());//把list assign到deque