版权声明:本文为博主原创文章,未经博主允许不得转载。
https://blog.csdn.net/sangyongjia/article/details/51122965 </div>
使用STL的三个境界:能用,明理,能扩展。本文属于第一个境界,如果结合了《STL源码解析》,则达到了第二个境界,如果项目中有需要,对STL进行了扩展则就达到了第三个境界!如果希望深刻理解vector的这些个成员函数,最好的办法是详细了解其内部实现,《STL源码解析》是个好途径!当然,也可以直接看编译器自带的<vector>的源码。
vector是C++标准模板库中的部分内容,vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组。
为了使用vector,必须包含头文件<vector>。另,vector属于std命名空间,因此需要通过命名限定,可以有如下三种方式,后两种方式更好,因为未引入的无关的内容。(依稀记的《Effective C++》的某个条款这个提过!)
using namespace std;
using namespace std::vector;
std::vector<int> vec;
现在以 std::vector<int> vec为例,描述相关函数的功能!
第一部分:
-
vec.begin()
//指向迭代器中第一个元素。
-
vec.end()
//指向迭代器中末端元素的下一个,指向一个不存在元素。
-
vec.push_back(elem)
//在尾部加入一个数据。
-
vec.pop_back()
//删除最后一个数据。
-
vec.capacity()
//vector可用空间的大小。
-
vec.size()
//返回容器中数据个数。
-
vec.empty()
//判断容器是否为空。
-
vec.front()
//传回第一个数据。
-
vec.back()
//传回最后一个数据,不检查这个数据是否存在。
-
vec.at(index)
//传回索引idx所指的数据,如果idx越界,抛出out_of_range。
-
vec.clear()
//移除容器中所有数据。
-
vec.erase(iterator)
//删除pos位置的数据,传回下一个数据的位置。
-
vec.erase(begin,end)
//删除[beg,end)区间的数据,传回下一个数据的位置。注意:begin和end为iterator
-
vec.insert(position,elem)
//在pos位置插入一个elem拷贝,传回新数据位置。
-
vec.insert(position,n,elem)
//在pos位置插入n个elem数据,无返回值。
-
vec.insert(position,begin,end)
//在pos位置插入在[beg,end)区间的数据,无返回值。
以下代码验证上述这些常用函数的功能:
-
#include<vector>
-
#include<iostream>
-
-
using
namespace
std;
-
-
-
int main()
-
{
-
vector<
int> vec(
3,
0);
-
vector<
int>::iterator iter;
-
vector<
int>::iterator begin=vec.begin();
-
vector<
int>::iterator end=vec.end();
-
cout<<
"vec:";
-
for(iter=begin; iter!=end; iter++)
-
{
-
static
std::
size_t i=
0;
-
cout<<*iter<<
",";
-
i++;
-
}
-
cout<<
endl;
-
cout<<
"size:"<<vec.size()<<
endl;
-
cout<<
"capacity:"<<vec.capacity()<<
endl;
-
//
-
cout<<
endl;
-
vec.push_back(
1);
-
vec.push_back(
2);
-
-
begin=vec.begin();
-
end=vec.end();
-
cout<<
"push back 1 and 2 based on above;vec:";
-
for(iter=begin; iter!=end; iter++)
-
{
-
static
std::
size_t j=
0;
-
cout<<*iter<<
",";
-
j++;
-
}
-
cout<<
endl;
-
cout<<
"size:"<<vec.size()<<
endl;
-
cout<<
"capacity:"<<vec.capacity()<<
endl;
-
//
-
cout<<
endl;
-
vec.pop_back();
-
-
begin=vec.begin();
-
end=vec.end();
-
cout<<
"pop one element based on above;vec:";
-
for(iter=begin; iter!=end; iter++)
-
{
-
static
std::
size_t k=
0;
-
cout<<*iter<<
",";
-
k++;
-
}
-
cout<<
endl;
-
cout<<
"size:"<<vec.size()<<
endl;
-
cout<<
"capacity:"<<vec.capacity()<<
endl;
-
/
-
begin=vec.begin();
-
end=vec.end();
-
cout<<
endl;
-
if(vec.empty())
-
{
-
cout<<
"vec is empty"<<
endl;
-
}
-
else
-
{
-
cout<<
"vec is not empty"<<
endl;
-
}
-
/
-
cout<<
endl;
-
cout<<
"based on the above:"<<
endl;
-
cout<<
" vec.front():"<<vec.front()<<
endl;
-
cout<<
" vec.back():"<<vec.back()<<
endl;
-
begin=vec.begin();
-
end=vec.end();
-
cout<<
" size:"<<vec.size()<<
endl;
-
cout<<
" capacity:"<<vec.capacity()<<
endl;
-
cout<<
"vec:";
-
for(iter=begin; iter!=end; iter++)
-
{
-
static
std::
size_t l=
0;
-
cout<<*iter<<
",";
-
l++;
-
}
-
cout<<
endl;
-
-
cout<<
endl;
-
cout<<
"call at(),based on the above:"<<
endl;
-
cout<<
" vec.at():"<<vec.at(
3)<<
endl;
-
begin=vec.begin();
-
end=vec.end();
-
cout<<
" size:"<<vec.size()<<
endl;
-
cout<<
" capacity:"<<vec.capacity()<<
endl;
-
cout<<
"vec:";
-
for(iter=begin; iter!=end; iter++)
-
{
-
static
std::
size_t m=
0;
-
cout<<*iter<<
",";
-
m++;
-
}
-
cout<<
endl;
-
//
-
cout<<
endl;
-
cout<<
"call clear(),based on the above:"<<
endl;
-
vec.clear();
-
begin=vec.begin();
-
end=vec.end();
-
cout<<
" size:"<<vec.size()<<
endl;
-
cout<<
" capacity:"<<vec.capacity()<<
endl;
-
cout<<
"vec:";
-
for(iter=begin; iter!=end; iter++)
-
{
-
static
std::
size_t m=
0;
-
cout<<*iter<<
",";
-
m++;
-
}
-
cout<<
endl;
-
//
-
cout<<
endl;
-
for(
int i=
1;i<
8;i++)
-
{
-
vec.push_back(i);
-
}
-
cout<<
"push_back 1,2,3,4,5,6,7 based on above;vec:";
-
begin=vec.begin();
-
end=vec.end();
-
for(iter=begin; iter!=end; iter++)
-
{
-
static
std::
size_t m=
0;
-
cout<<*iter<<
",";
-
m++;
-
}
-
-
cout<<
endl;
-
vec.erase(vec.begin()+
2);
-
cout<<
"call vec.erase(3),vec:";
-
begin=vec.begin();
-
end=vec.end();
-
for(iter=begin; iter!=end; iter++)
-
{
-
static
std::
size_t m=
0;
-
cout<<*iter<<
",";
-
m++;
-
}
-
cout<<
endl;
-
cout<<
" size:"<<vec.size()<<
endl;
-
cout<<
" capacity:"<<vec.capacity()<<
endl;
-
//
-
cout<<
endl;
-
vec.erase(vec.begin()+
1,vec.begin()+
3);
-
cout<<
"call vec.erase(1,3),vec:";
-
begin=vec.begin();
-
end=vec.end();
-
for(iter=begin; iter!=end; iter++)
-
{
-
static
std::
size_t m=
0;
-
cout<<*iter<<
",";
-
m++;
-
}
-
cout<<
endl;
-
cout<<
" size:"<<vec.size()<<
endl;
-
cout<<
" capacity:"<<vec.capacity()<<
endl;
-
return
1;<span style=
"font-family: Arial, Helvetica, sans-serif;">}</span>
输出结果如下:
vector中v[i]与v.at(i)的区别:参见:http://www.cnblogs.com/zhuyf87/archive/2012/12/06/2805579.html
-
void f(vector<int> &v)
-
{
-
v[
0];
// A
-
v.at[
0];
// B
-
}
如果v非空,A行和B行没有任何区别。如果v为空,B行会抛出std::out_of_range异常,A行的行为未定义。
c++标准不要求vector<T>::operator[]进行下标越界检查,原因是为了效率,总是强制下标越界检查会增加程序的性能开销。设计vector是用来代替内置数组的,所以效率问题也应该考虑。不过使用operator[]就要自己承担越界风险了。如果需要下标越界检查,请使用at。
第二部分:
-
assign函数原型及功能:
-
void assign(const_iterator first,const_iterator last);
//功能:将区间[first,last)的元素赋值到当前的vector中,当前vector会清除掉容器中之前的内容。
-
void assign(size_type n,const T& x = T());
//功能:赋n个值为x的元素到当前vector中,当前vector会清除掉容器中之前的内容。
以下函数验证assign函数的功能:
-
#include <vector>
-
#include <iostream>
-
using
namespace
std;
-
int main( )
-
{
-
vector<
int> v1, v2, v3;
-
vector<
int>::iterator iter;
-
for(
int i=
10; i<
60; i+=
10)
-
{
-
v1.push_back(i);
-
}
-
v2.push_back(
1);
-
v2.push_back(
2);
-
-
cout <<
"v1 = " ;
-
for (iter = v1.begin(); iter != v1.end(); iter++)
-
{
-
cout << *iter <<
" ";
-
}
-
cout <<
endl;
-
-
cout <<
"v2 = ";
-
for (iter = v2.begin(); iter != v2.end(); iter++)
-
cout << *iter <<
" ";
-
cout <<
endl;
-
-
-
v1.assign(v2.begin(), v2.end());
-
cout <<
"v2 = ";
-
for (iter = v2.begin(); iter != v2.end(); iter++)
-
cout << *iter <<
" ";
-
cout <<
endl;
-
v3=v1;
-
v3.assign(
4,
3) ;
-
cout <<
"v3 = ";
-
for (iter = v3.begin(); iter != v3.end(); iter++)
-
cout << *iter <<
" ";
-
cout <<
endl;
-
return
0;
-
}
运行结果如下:
第三部分:
-
vec.rbegin()
//传回一个vector的最后一个数据的指针。
-
vec.rend()
// 传回一个vector的第一个数据前一个位置的指针。?
验证代码如下:
-
#include <vector>
-
#include <iostream>
-
using
namespace
std;
-
int main( )
-
{
-
vector<
int> v1, v2, v3;
-
vector<
int>::iterator iter;
-
for(
int i=
10; i<
60; i+=
10)
-
{
-
v1.push_back(i);
-
}
-
v2.push_back(
1);
-
v2.push_back(
2);
-
-
cout <<
"v1 = " ;
-
for (iter = v1.begin(); iter != v1.end(); iter++)
-
{
-
cout << *iter <<
" ";
-
}
-
cout <<
endl;
-
-
cout <<
"v2 = ";
-
for (iter = v2.begin(); iter != v2.end(); iter++)
-
cout << *iter <<
" ";
-
cout <<
endl;
-
vector<
int>::reverse_iterator r_iter;
-
cout <<
"v1 in reverse ";
-
for (r_iter = v1.rbegin(); r_iter != v1.rend(); r_iter++)
-
cout << *r_iter <<
" ";
-
cout <<
endl;
-
cout<<
"v1.rbegin():"<<*v1.rbegin()<<
endl;
-
cout<<
"v1.rbegin():"<<(*(v1.rbegin()--))<<
endl;
-
cout<<
"v1.rend()--:"<<*(v1.rend()--)<<
endl;
-
-
cout<<
"v1.rend()++:"<<*(v1.rend()++)<<
endl;
-
-
return
0;
-
}
输出结果为:
此处有个疑问:对(*(v1.rbegin()++))、(*(v1.begin()++))、(*(v1.rbegin()--))、(*(v1.begin()--))均没达到预期,需要看下其内部究竟是怎么实现的!
另外,注意:企图直接打印迭代器,编译是通不过的!eg:cout<< v1.begin();
第四部分:
-
vec.resize(num)
//重新指定vector的长度。
-
vec.resize(num,value)
//重新指定vector的长度。并设定新增的元素的值
当需要以vec[size+1]=vec[j];的方式对超过vector的size赋值时,都需要先调用下resize()函数,如果直接对超出vector.size()的位置赋值,编译不能通过!
-
vec.swap(vec1)
//
-
swap(vec,vec1)
//
-
#include<vector>
-
#include<iostream>
-
-
using
namespace
std;
-
-
int main()
-
{
-
vector<
int> vec(
3,
0);
-
vector<
int>::iterator iter;
-
vector<
int>::iterator begin=vec.begin();
-
vector<
int>::iterator end=vec.end();
-
cout<<
"vec:";
-
for(iter=begin; iter!=end; iter++)
-
{
-
static
std::
size_t i=
0;
-
cout<<*iter<<
",";
-
i++;
-
}
-
cout<<
endl;
-
vec.push_back(
7);
-
cout<<
"size:"<<vec.size()<<
endl;
-
cout<<
"capacity:"<<vec.capacity()<<
endl;
-
vector<
int>(vec).swap(vec);
-
cout<<
"vector<int>(vec)-swap-capacity:"<<vec.capacity()<<
endl;
-
cout<<
"vector<int>(vec)-swap-size:"<<vec.size()<<
endl;
-
-
-
{
-
vector<
int> temp(vec);
-
temp.swap(vec);
-
cout<<
"temp-swap-capacity:"<<vec.capacity()<<
endl;
-
cout<<
"temp-swap-size:"<<vec.size()<<
endl;
-
}
-
-
-
vector<
int>().swap(vec);
-
cout<<
"vector<int>()-swap-capacity:"<<vec.capacity()<<
endl;
-
cout<<
"vector<int>()-swap-size:"<<vec.size()<<
endl;
-
return
1;
-
}
输出结果为:
-
#include<vector>
-
#include<iostream>
-
#include<algorithm>
-
using
namespace
std;
-
-
-
int main()
-
{
-
vector<
int> vec(
3,
0);
-
vector<
int>::iterator iter;
-
vector<
int>::iterator begin=vec.begin();
-
vector<
int>::iterator end=vec.end();
-
cout<<
"vec:";
-
for(iter=begin; iter!=end; iter++)
-
{
-
static
std::
size_t i=
0;
-
cout<<*iter<<
",";
-
i++;
-
}
-
cout<<
endl;
-
vec.push_back(
7);
-
cout<<
"vec size:"<<vec.size()<<
endl;
-
cout<<
"vec capacity:"<<vec.capacity()<<
endl;
-
-
vector<
int> vec1(
3,
1);
-
vec1.push_back(
6);
-
cout<<
"vec1 size:"<<vec1.size()<<
endl;
-
cout<<
"vec1 capacity:"<<vec1.capacity()<<
endl;
-
-
swap(vec,vec1);
-
begin=vec.begin();
-
end=vec.end();
-
cout<<
"after swap vec:";
-
for(iter=begin; iter!=end; iter++)
-
{
-
cout<<*iter<<
",";
-
}
-
cout<<
"vec size after swap():"<<vec.size()<<
endl;
-
cout<<
"vec capacity after swap():"<<vec.capacity()<<
endl;
-
-
begin=vec1.begin();
-
end=vec1.end();
-
cout<<
"after swap vec1:";
-
for(iter=begin; iter!=end; iter++)
-
{
-
cout<<*iter<<
",";
-
}
-
cout<<
"vec1 size after swap():"<<vec1.size()<<
endl;
-
cout<<
"vec1 capacity after swap():"<<vec1.capacity()<<
endl;
-
return
0;
-
}
输出结果为:
该结果表明<algorithm>中的函数swap(),只是交换两个vector中的内容,其原本的size和capacity均不做改变!
vec.reserve()//设定capacity的值,如果小于原本的capacity的值则保持为原本的capacity的值。
以下为显而易见的操作:
operator[]://此函数返回的是容器中指定位置的一个引用。
operattor*://指针的取址操作
若干种创建方式(vector的构造函数)
vector<type> vec
vector<type> vec(vec1)
vector<type> vec=vec1
vector<type> vec(n)
vector<type> vec(n,elem)
vector<type> vec(begin,end)
vector<type> vec{a,b,c,……}
vector<type> vec={a,b,c,……}