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