vector作为动态扩展数组,使用相对方便。并且在增加或者删除一个元素时,内建机制能够保证它所划分的地址是连续的。下面是vector的几个常用函数,以及几个需要注意的问题。
使用vector容器之前需要include <vector>。
1. capacity()
返回当前vector的容量,也就是分配的空间大小,最多能容纳的元素数量;
2. size()
返回当前vector的体积,也就是已经使用了的空间大小,已经容纳了的元素数量;
3. resize(n)
将当前vector体积缩放至大小为n;这里注意是体积而不是容量,因为如果n小于原来的空间,那空间是不会被释放的;如果n大于原来的空间,那体积和容量都会被扩大到n,如果是int类型,向vector中填充的都是0;
3. clear()
清空了容器内的元素,但是已经分配了的空间并不会被释放;
4. push_back()
向vector中末尾压入一个元素,如果vector中有已经分配的空间会放入分配空间中,如果超出就要再次分配新的空间,为了保证分配空间的连续,往往会多分配一部分,例如:执行
#include <vector>
void main()
{
std::vector<int> vec;
for(int i=0; i<10; i++)
{
vec.push_back(100);
}
vec.push_back(314);
vec.push_back(314);
std::cout << vec.capacity() << " " << vec.size() << std::endl;
return ;
}
此时得到的capacity并不是12,而是15(我的运行结果),这就是超出时多分配的一部分空间。
5. pop_back()
与之对应的是从容器末尾弹出一个元素并返回,当然容器的容量不变,体积减一;
6. erase()
删除一个元素,它的输入是迭代器指针指向的元素,利用迭代器删除元素稍后会有示例。
7. std::vector<Tx>::iterator,其中Tx表示的是存储变量类型,
迭代器iterator是vector最正统的访问元素的方法,它是一个指向vector中元素的指针,因此声明中需要Tx信息。空间的连续分布使得iterator可以很方便地访问各个元素。例如:上面的代码也可以写成
#include <vector>
void main()
{
std::vector<int> vec(10); // 分配10个int的空间,默认为0
for(std::vector<int>::iterator it=vec.begin(); it<vec.end(); it++)
{
*it = 100;
}
vec.push_back(314);
vec.push_back(314);
std::cout << vec.capacity() << " " << vec.size() << std::endl;
return ;
}
注意这里如果不是用迭代器,而是直接继续向vector中push_back的话,得到的将是一个size双倍的vector,也就是说当声明vec变量时已经分配了空间并且默认为0,就只能通过迭代器来访问,push_back不能访问这些空间。
8. 删除某个元素
回到刚才erase的部分,删除vector中的某个元素有两种方法:仅写出伪码
std::vector<int>::iterator it = vec.begin();
it += Index; // 要删除的元素序号,从0开始
vec.erase(it);
注意一旦被删除后,it所指向的元素不再存在,因而it++这样的操作就会出现错误。所以尽量使用it+n这样的表达来删除一个元素,而不是it本身。
另外也可以把要删除的元素和末尾的元素交换,然后pop_back()也是可以的。
9. swap()
释放vector占据的空间。
前面提到几个注意,vector的空间没有被释放掉。当退出vector变量所在的作用域时,为其分配的空间就会被释放掉,如果存储的是类,就会调取类的析构函数,但是如果是类的指针,就只能通过指针挨个儿去释放空间,然后clear(),然后退出作用域。
如果想要强制释放vector的空间,就用到上面的swap()。它的作用是要把当前vector和一个空的vector交换,然后这个空的vector存在于一个有限的作用域中,退出时得到释放就可以了。例如:
要释放已经分配了空间并存储数据的vec;
std::vector<int>().swap(vec);
我理解来,就是有一个新的空vector它要和vec交换内容,得到vec的内容后这个空vector就退出了自己的作用域(就在这一行内),而vec已经置空。
10. reserve()与resize()的区别
vector 的reserve增加了vector的capacity,但是它的size没有改变!而resize改变了vector的capacity同时也增加了它的size!
原因如下:
reserve是容器预留空间,但在空间内不真正创建元素对象,所以在没有添加新的对象之前,不能引用容器内的元素。加入新的元素时,要调用push_back()/insert()函数。
resize是改变容器的大小,且在创建对象,因此,调用这个函数之后,就可以引用容器内的对象了,因此当加入新的元素时,用operator[]操作符,或者用迭代器来引用元素对象。此时再调用push_back()函数,是加在这个新的空间后面的。