目录
vector 的数据安排以及操作方式,与 array 非常相似,差别在于:
- array 是静态空间;
- vector 是动态空间,随着元素的加入,它的内部机制会自动扩充空间以容纳新元素。
1. 数据结构:线性连续空间。
Vector 以两个两个迭代器 _Myfirst 和 _Mylast 分别指向配置得来的连续空间中目前已使用的范围,并以迭代器 _Myend 指向整块连续内存空间的尾端。
2. 迭代器:随机迭代器。
vector 维护一个线性空间,不论元素的类型如何,普通指针都可以作为vector的迭代器。因为vector迭代器所需要的操作行为,如:operator->,operator++,operator+=等,普通指针天生具备。vector 支持随机存取,而普通指针正有这个能力。所以vector提供的是随机访问迭代器(Random Access Iterators)。
由此,可知
Vector<int>::iterator a;
Vector<Maker>::Iterator b;
a 的类型其实就是 int*,b 的类型就是 Maker*。
三. vector容器动态增长原理:
① 当存储空间不够时,会另开辟一块大的空间,然后把数据拷贝过去,最后销毁原来的空间;
② 申请的空间,会比用户需求大一点;
③ 对vector的任何操作,一旦引起空间的重新配置,指向原 vector 的所有迭代器就都失效了。
四. vector 常用API:
1. vector 构造函数
vector<T> v; //采用模板实现类实现,默认构造函数
vector(v.begin(), v.end()); //将v[begin(), end()]区间中的元素拷贝给本身
vector(n, elem); //构造函数将n个elem拷贝给本身
vector(const vector& vec); //拷贝构造函数
2. vector 赋值操作
assign(begin, end); //将[begin, end)区间中的数据拷贝赋值给本身
assign(n, elem); //将n个elem拷贝赋值给本身
vector&operator=(const vector &vec); //重载等号操作符
swap(vec); // 将vec与本身的元素互换
3. vector 大小操作
size(); //返回容器中元素的个数
empty(); //判断容器是否为空
resize(int num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。
//如果容器变短,则末尾超出容器长度的元素被删除。
resize(int num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。
//如果容器变短,则末尾超出容器长度的元素被删除。
capacity(); //容器的容量
reserve(int len); //容器预留len个元素长度,预留位置不初始化,元素不可访问。
swap 的使用:缩小容量
① capacity 比 size 略微大点;
② resize 只减小了size,capacity 并没有变;
③ 调用拷贝构造,v2的 capacity 减小;
④ 可看成是:vector<int>v2(v).swap(v); 只是把匿名对象的名字隐藏了。
4. vector 数据存取操作
at(int idx); //返回索引idx所指的数据,如果idx越界,抛出out_of_range异常。
operator[]; //返回索引idx所指的数据,越界时,运行直接报错
front(); //返回容器中第一个数据元素
back(); //返回容器中最后一个数据元素
5. vector 插入和删除操作
insert(const_iterator pos, int count,ele); //迭代器指向位置pos插入count个元素ele.
push_back(ele); //尾部插入元素ele
pop_back(); //删除最后一个元素
erase(const_iterator start, const_iterator end); //删除迭代器从start到end之间的元素
erase(const_iterator pos); //删除迭代器指向的元素
clear(); //删除容器中所有元素
6. 注意:
resize:开辟空间并初始化;
reserve:开辟空间,但不初始化,没有初始化的空间不能访问。如果容器要存储大量数据时,要先开辟空间,避免多次申请空间。
swap:缩小容器的容量。