C++ STL学习之二:序列式容器vector深入学习

vector的空间可扩充,支持随机存取访问,是一段连续线性的空间。所以它是动态空间,与之对比的array是静态的空间,不可扩充。简单来说,vector是数组的增强版。

Vector:动态空间,自扩充。吃多少用多少。因为支持随机存取,所以提供Random Access Iterators。普通指针可以作为vector的迭代器。vector<int>::iterator iter,则iter类型为int *

Vector数据结构:

迭代器startfinish执行已经被使用的范围,end_of_storage表示可用空间的尾部

容量:用于扩充,>=vector的大小

动态增加大小的原理:

取原大小两倍空间,拷贝原容器内容至新空间,成功了释放原空间,失败了仍然用原空间。

Inset(position,n,x):函数思路:

1)若备用空间>=新增元素个数,(1)若插入点后现有元素个数>新增元素个数,则将插入点后的所有元素放到储备空间的最后面,然后在插入点后插入新增元素;(2)若插入点后现有元素个数<=新增元素个数,则先在储备空间中复制若干元素,然后将插入点后的老元素复制到储备空间的后面,腾出的地方插入新元素

2)若备用空间<新增元素个数,分配额外内存为原内存两倍。将旧vector插入点之前元素复制到新空间,将新增元素复制到新空间,将旧v ector插入点之后元素复制到新空间

vector的容量十分重要,是因为:

1、一旦内存重新配置,与之相关的所有的reference、pointers、iterators都会失效。

2、内存配置很费时。

解决这个问题的方法有:

1、可以使用reserve()保留适当容量,减少重新配置内存的次数。示例代码:

  1. vector<string> sentence(1);  
  2. sentence.reserve(50);  
2、在初始化期间向构造函数传递附加参数,构造出足够的空间。
  1. vector<T> v(5);  
当然,这种元素的型别必须提供默认构造函数。但是如果元素的型别比较复杂,初始化操作也很耗时。如果只是为了保留足够的内存,使用方法1较好。

注意:reserve不能缩减vector的容量。由此,我们可以知道,即使删除元素,其reference、pointers、iterators也会继续有效,指向动作发生前的位置。

但是插入操作可能使reference、pointers、iterators失效(因为可能会导致重新配置空间)。


使用swap函数可以缩减vector容量。因为两个vector交换内容后,他们的容量也会互换。

1、

  1. template<class T>  
  2. void shrinkCapacity(vector<T> &v)  
  3. {  
  4.     vector<T> tmp(v);  
  5.     v.swap(tmp);  
  6. }  
2、
  1. vector<T>(v).swap(v);  
面两种方法等价。
都是先构造出一个临时vector对象,以v的元素进行初始化,再与v进行交换。需要注意的是:临时对象一般都是精确分配实际所需的内存。所以能够起到减小vector容量的效果。


迭代器失效的两种情况是:

1、在一个较小的位置上删除或者是移动元素。

2、由于容量的变换引起内存重新分配。

插入和移除元素,都会使“作用点”之后的各元素的reference、pointers、iterators失效。插入操作还可能引发内存重新分配,那么该容器上的所有的reference、pointers、iterators都会失效。


现在的C++标准保证vector的元素必须分布于连续空间中。对于vector中的一个合法索引,满足下列表达式:

&v[i] = &v[0] + i;

我们必须保证vector能够容纳所有数据。如果使用的是C-String,记住最后有个'\0'。

只要我们需要一个元素型别为T的数组,就可以采用vector<T>,然后传递第一个元素的地址给它。

注意:千万不要把迭代器当做第一元素的地址来传递。因为vector迭代器是由实作版本定义的,不一定是一个一般指针。

  1. printf("%s",v.begin());//ERROR(might work,but not portable)
  2. printf("%s",&v[0]);//OK  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值