一 vector概述:
(1)概述:
vector塑造出一个动态数组,因此,它本身是“将元素置于动态数组中加以管理”的一个抽象概念。不过STL Stantard并未要求必须以动态数组实作vector,只是规定了相应条件和操作复杂度。
(2) vector与array的区别:
1.array是静态空间,一旦分配就不能改变;要换个大(或小)一点的空间,可以,但是一切琐碎细节由客户端自己处理:首先配置一块新区间,然后将元素从原来空间一一搬到新的空间,再把原来的空间释放给系统。
2.vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素。vector的实现技术,关键在于其对大小的控制以及重新配置时的数据移动效率。
*动态增加大小(配置新空间/数据移动/释放旧空间):并不是在原空间之后接续新空间(因为无法保证原空间之后尚有可配置的空间),而是以原大小的两倍另外配置一块较大空间,然后将原内容拷贝过来,然后才开始在原内容之后构造新元素,并释放空间。
*因此,对vector的任何操作,一旦引起空间的重新配置,指向原vector的所有迭代器就都失效了,务必小心。
(3) vector特点:
*支持随机存取,即可以利用索引直接存取任何一个元素(常数时间)。
*在尾部添加和删除元素均非常快速。
*在头部或中间安插和删除元素比较费时,因为,为了保持原本的相对次序,安插点之后的所有元素都必须移动,挪出位子。
(4) 大小(size)和容量(capacity):
*vector优异性能的秘诀之一,就是配置比所容纳的元素所需更多的内存。
*vector中用于操作大小的函数有:size()、empty()、max_size()、capacity()和reserve()。
*size():返回当前容器的元素数量。
empty():判断容器是否为空,比size()==0高效。
max_size():返回容器所能容纳的最大元素数量。
capacity():返回vector实际能够容纳的元素数量。如果超越这个数量,vector就有必要重新配置内部存储器。
reserve():告诉vector容器应用预留多少元素的存储空间。
(5)vector的容量之所以如此重要,有以下两个原因:
1.一旦内存重新配置,和vector元素相关的所有references、pointers、iterators都会失效。
2.内存重新配置很耗时间(配置新空间/数据移动/释放旧空间)。
3.vector的容量,概念上和strings类似。不过有一个大的不同点:vector不能使用reserve()来缩减容量。
4.安插和删除元素,都会导致“作用点”之后的各元素的references、pointers、iterators失效。如果安插操作引起重新分配内存,那么该容器身上的所有的references、pointers、iterators都会失效。
二 vector的相关操作
(1)构造、拷贝和析构
(2)非变动性操作
(3)赋值
下表列出“将新元素赋值给vectors,并将旧元素全部移除”的方法。
(4)元素的存取
下表列出用来直接存取vector元素的全部操作函数。只有at()会进行范围检查,如果索引越界,at()会抛出out_of_range异常。其它函数都不检查,如果发生越界错误,会引发未定义行为。
所以,调用operator[]时,必须确定索引有效;调用front()和back()都必须确定容器不为空。
(5)迭代器相关的函数
(6)安插和删除
*安插和删除元素,都会导致“作用点”之后的各元素的references、pointers、iterators失效。如果安插操作引起重新分配内存,那么该容器身上的所有的references、pointers、iterators都会失效。
*在尾部添加和删除元素均非常快速。
*在头部或中间安插和删除元素比较费时,因为,为了保持原本的相对次序,安插点之后的所有元素都必须移动,挪出位子。