vector<shape>::size_type max_size = my_shapes.max_size();
当前容器的实际尺寸---- 已有的元素个数用size():
vector<shape>::size_type size = my_shapes.size();可以用 capacity()来取得vector 中已分配内存的元素个数:
vector<int> v;
vector<int>::size_type capacity = v.capacity();
vector 类似于数组,可以 使用下标[]访问:
vector<int> v(10);
v[0] = 101;
注意到这里预先给 10 个元素分配了空间。
你也可以使用vector 提供的插入函数来动态的扩展容器。成员函数push_back()就在vector 的尾部添加了一个元素:
v.push_back(3);也可以用 insert()函数完成同样的工作:
v.insert(v.end(), 3);
这里insert()成员函数需要两个参数:一个指向容器中指定位置的迭代器(iterator),一个待插入的元素。insert()将元素 插入到迭代器指定元素之前。
现在对迭代器(Iterator)做点解释。Iterator是指针(pointer) 的泛化,iterator 要求定义 operator*,它返回指定类型的值。Iterator 常常和容器联系在一起。例子:
vector<int> v(3);v[0] = 5;
v[1] = 2;
v[2] = 7;
vector<int>::iterator first = v.begin();
vector<int>::iterator last = v.end();
while (first != last)
cout << *first++ << “ “;
上面代码的输出是:
5 2 7
begin()返回的是 vector中第一个元素的 iterator ,而 end()返回的并不是最后一个元素的 iterator,而是past the last element 。在STL 中叫past-the-end iterator 。
你可以用以下的几种方法声明一个vector 对象:
vector<float> v(5, 3.25); //初始化有5 个元素,其值都是3.25
vector<float> v_new1(v);
vector<float> v_new2 = v;
vector<float> v_new3(v.begin(), v.end());
这四个vector 对象是相等的,可以用operator==来判断。
其余常用的vector 成员函数有:
empty() :判断vector 是否为空
front() :取得vector 的第一个元素
back() :取得vector 的最后一个元素
pop_back() :去掉最后一个元素
erase() :去掉某个iterator 或者iterator 区间指定的元素
vector::erase():从指定容器删除指定位置的元素或某段范围内的元素
vector::erase()方法有两种重载形式
如下:
iterator erase(
1.iterator
如果是删除指定位置的元素时:
返回值是一个迭代器,指向删除元素下一个元素;如果是删除某范围内的元素时:返回值也表示一个迭代器,指向最后一个删除元素的下一个元素;
- #include <vector>
- #include <iostream>
- int
main( ) - {
- using
namespace std; - vector <int> v1;
- vector <int>::iterator
Iter; - v1.push_back(
10 ); - v1.push_back(
20 ); - v1.push_back(
30 ); - v1.push_back(
40 ); - v1.push_back(
50 ); - cout << "v1 =" ;
- for
( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) -
cout << " " << *Iter; - cout << endl;
- v1.erase(
v1.begin( ) ); - cout << "v1 =";
- for
( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) -
cout << " " << *Iter; - cout << endl;
- v1.erase(
v1.begin( ) + 1, v1.begin( ) + 3 ); - cout << "v1 =";
- for
( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) -
cout << " " << *Iter; - cout << endl;
- }
Output
v1 = 10 20 30 40 50
v1 = 20 30 40 50
v1 = 20 50
(解释:删除的是Iter指针之间的数)
大家可以知道,需删除元素10只要指定该元素对应的迭代器传给erase就OK了;
那现在如果该容器中有两个元素10要怎么删除呢?
接着我做下修改,向容器中添加一新的元素10
- v1.push_back( 10 );
大多数初学者在不熟知erase的原理的时候,也会像我一样这样处理,
一一遍历容器找到元素值为10,然后一一删除
- for(Iter = v1.begin(); Iter != v1.end(); Iter++)
- {
-
if(*Iter == 10) -
{ -
v1.erase(Iter); -
} - }
当试着重新build程序后运行,会出现包含有如下信息的错误
_Myptr < ((_Myvec *)(this->_Mycont))->_Mylast
其他出现这种原因是没搞懂erase的原理,当调用erase()后Iter迭代器就失效了,变成了一野指针。
所以要处理这种问题,关键是要解决调用erase()方法后,Iter迭代器变成野指针的问题,
这个时候呢给他赋一个新的迭代器给他。
- for(Iter = v1.begin(); Iter != v1.end(); Iter++)
- {
-
if(*Iter == 10) -
{ -
v1.erase(Iter); -
Iter = v1.begin(); //当erase后,旧的容器会被重新整理成一个新的容器 -
} - }
重新Iter迭代器指定下一个元素.
上面那种方法是给Iter重新赋于新v1的begin迭代器。
还有一种方法是直接赋删除元素的下一个迭代器给Iter
实现方法的代码如下:
- for(Iter = v1.begin(); Iter != v1.end(); Iter++)
- {
-
if(*Iter == 10) -
{ -
Iter = v1.erase(Iter);//Iter为删除元素的下一个元素的迭代器 -
//即第一次这段语句后Iter 会是20,大家可以通过debug调试出来查看下数值 -
} -
-
if(Iter == v1.end()) //要控制迭代器不能超过整个容器 -
{ -
break; -
} - }
vector<int> veci;
veci.push_back(1);
veci.push_back(2);
veci.push_back(3);
veci.push_back(4);
veci.push_back(5);
veci.push_back(3);
veci.push_back(2);
veci.push_back(3);
for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
{
if( *iter == 3)
veci.erase(iter);
}
乍一看这段代码,很正常。其实这里面隐藏着一个很严重的错误:当veci.erase(iter)之后,iter就变成了一个野指针,对一个野指针进行 iter++ 是肯定会出错的。
for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
{
if( *iter == 3)
iter = veci.erase(iter);
}
这段代码也是错误的:1)无法删除两个连续的"3"; 2)当3位于vector最后位置的时候,也会出错(在veci.end()上执行 ++ 操作)
正确的代码应该为:
for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); )
{
if( *iter == 3)
iter = veci.erase(iter);
else
iter ++ ;
}
还有一种删除的办法:就是讲erase和remove配合使用~
vector中erase是真正删除了元素, 迭代器访问不到了。
algorithm中的remove只是简单的把要remove的元素移到了容器最后面,迭代器还是可以访问到的。
vector<int> array;
array.erase(remove(array.begin(),array.end(),6),array.end());
删除数组中所有元素等于6的元素
解释:remove只是把待删除的元素移位到了数据序列的尾部,而并未真正的删除元素,
remove函数返回待删除序列的首个元素的迭代器
比如说,123123,remove(1),那么序列变成了232311,返回一个迭代器,指向第一个1的位置,这是配合erase()函数,把这个迭代器作参数,可以把后,面两个1删除,数据序列变成了2323。
C++ Vector排序
- vector< int > vi ;
- vi.push_back(1);
- vi.push_back(3);
- vi.push_back(0);
- sort(vi.begin() , vi.end()); /// /小到大
- reverse(vi.begin(),vi.end()) /// 从大道小
顺序访问
- vector < int > vi ;
- for( int i = 0 ; i < 10 ; i ++)
- {
- vi.push_back(i);
- }
- for(int i = 0 ; i < 10 ; i ++) /// 第一种调用方法
- {
- cout <<vi[i] <<" " ;
- }
- for(vector<int>::iterator it = vi.begin() ; it !=vi.end() ; it++) ///第二种调用方法
- {
- cout << *it << " " ;
- }
寻找
- vector < int > vi ;
- for( int i = 0 ; i < 10 ; i ++)
- {
- vi.push_back(i);
- }
- vector < int >::interator it = find(vi.begin() , vi.end,3) ;
- cout << *it << endl ; ///返回容器内找到值的位置。
使用数组对C++ Vector进行初始化
- int i[10] ={1,2,3,4,5,6,7,78,8} ;
- vector<int> vi(i+1,i+3); ///从第2个元素到第三个元素
- for(vector <int>::interator it = vi.begin() ; it != vi.end() ; it++)
- {
- cout << *it <<" " ;
- }
Vector调用clear()之后,只会把size设置为0,而内存空间并没有释放。 vector 中的内建有内存管理,当 vector 离开它的生存期的时候,它的析构函数会把 vector 中的元素销毁,并释放它们所占用的空间,所以用 vector 一般不用显式释放 —— 不过,如果你 vector 中存放的是指针,那么当 vector 销毁时,那些指针指向的对象不会被销毁,那些内存不会被释放。
在《effective STL》和其实很多C++文章中都有指明,用clear()无法保证内存回收。但是swap技法可以。具体方法如下所示:
vector<int> nums;
nums.push_back(1);
nums.push_back(1);
nums.push_back(2);
nums.push_back(2);
vector<int>().swap(nums); //或者nums.swap(vector<int> ());