1.vector的特性
vector的数据安排以及操作方式与array非常类似,两者的唯一差别在于空间运用的灵活性。
vetor是动态空间,随着元素的加入,他的内部机制会自行扩充空间以容纳新元素。
2.vector的迭代器
因为vector维护的是一个连续的线性空间,所以不论其元素型别为何,普通指针都可以作为vector的迭代器而满足所有必要条件。
如operator*,operator->,operator++,operator--,operator+,operator-,普通指针天生就具备。
所以在vector里面:
template<class T,class Alloc = alloc>
class vector
{
public:
typedef T value_type;
typedef value_type* iterator;
...
}
所以当你写出
vector<int>::iterator ivite;
vector<Shape>::iterator svite;
其中ivite的型别就是int*,svite的型别其实就是Shape*
3.vector的内存构造与管理
由于vector采用的数据结构非常简单,线型的连续控件,以两个迭代器start和finish分别指向配置得来的连续空间中目前已被使用的范围,并以end_of_storage
指向整块连续空间的尾端。在实际配置空间时,配置的空间往往比用户当前需要的空间要大一些,以免除频繁扩张容量的繁琐操作。当用户往里面添加元素的时候,如果当前还有剩余空间就直接加入到线性空间后面,否则执行容器扩张:重新配置、元素移动、释放原空间。核心代码如下
const size_type old_size = size();
const size_type len = old_size != 0?2*old_size:1;
//以上配置原则:如果原大小为0,则配置1(个)
//如果原大小不为0,则配置原大小的两倍
iterator new_start = data_allocator::allocate(len);
iterator new_finish = new_start;
try{
//将原vector内容拷贝至新vector
new_finish = uninitialized_copy(start,position,new_start);
construct(new_finsih,x);
};
catch(...)
{
destroy(new_start,new_finish);
data_allocator::deallocate(new_Start,len);
throw;
}
//析构原有vector
destroy(begin(),end());
deallocate();
//调整迭代器,指向新vector
start = new_start;
finish = new_finsih;
end_of_storage = new_start+len;
注意:对于vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器就都失效了,需要避免此类错误。