这节第一次看自闭了 ,又看了一遍,照书上代码敲了敲补充了下细节,才算明白。
了解Iterator(泛型指针)
注:书上的代码在拼合的时候,有些细节没给出,也没有提醒,需要你自己悟出来或者搜索一下。
直接以一份代码来说明这一节
#include<iostream>
#include<vector>
#include<list>//这个头文件得写,因为你用到了list,书上没说。。。。
using namespace std;
template<typename elemType>
void display(const vector<elemType>&vec,ostream &os=cout)
{
typename vector<elemType>::const_iterator iter=vec.begin();//原书中未在vector前加typename,你不加,编译器给你报错。(去掉试试)
typename vector<elemType>::const_iterator end_it=vec.end();//如果是面对const vector,则用const_iterator来进行操作
//如果面对vector,就用iterator即可
//若vec是空vector,则iter=end_it,for循环不会被执行
for(;iter!=end_it;++iter)
{
os<<*iter<<' ';
}
os<<endl;
}
//重新实现find()函数
template<typename IteratorType,typename elemType>IteratorType find(IteratorType first,IteratorType last,const elemType &value)
{
for(;first!=last;++first)
{
if(value==*first)
{
return first;
}
}
return last;//走到这里证明没找到和value一样的元素,直接返回last指针。。。
}
int main()
{
const int asize=8;//用泛型指针作为形参的find()来处理array、vector和list
int ia[asize]={1,1,2,3,5,8,13,21};
vector<int> ivec(ia,ia+asize);//容器被赋初值
list<int> ilist(ia,ia+asize);//容器被赋初值
display(ivec);
int *pia=find(ia,ia+asize,5);
if(pia!=ia+asize)//这里对应着return last,在传参的时候last=ia+asize
{
//走进了if,证明在容器里找到了指定元素
cout<<"*pia:"<<*pia<<endl;
}
vector<int>::iterator it;//定义泛型指针
it=find(ivec.begin(),ivec.end(),14);//注意这个;要写上//find()函数传入容器的泛型算法
if(it!=ivec.end())
{
//走进了if,证明找到了指定元素
cout<<"*it:"<<*it<<endl;
}
list<int>::iterator iter;//定义泛型指针
iter=find(ilist.begin(),ilist.end(),21);
if(iter!=ilist.end())
{
cout<<"*iter:"<<*iter<<endl;
}
//若都没找到就什么也不做
return 0;
}
首先看下头文件
#include<iostream>
#include<vector>
#include<list>//这个头文件得写,因为你用到了list,书上没说。。。。
using namespace std;
因为你用了list这个容器,所以你必须把相应的头文件包含(据推断,用哪个容器就包含哪个容器相应的头文件,array除外)。
template<typename elemType>
void display(const vector<elemType>&vec,ostream &os=cout)
{
typename vector<elemType>::const_iterator iter=vec.begin();//原书中未在vector前加typename,你不加,编译器给你报错。(去掉试试)//iterator的定义
typename vector<elemType>::const_iterator end_it=vec.end();//如果是面对const vector,则用const_iterator来进行操作
//如果面对vector,就用iterator即可
//若vec是空vector,则iter=end_it,for循环不会被执行
for(;iter!=end_it;++iter)
{
os<<*iter<<' ';
}
os<<endl;
}
这是显示vector所有元素的函数(我定义为模板函数)。首次出现泛型指针的定义,即iter被定义为一个iterator,iter指向一个vector,vector元素类型为elemType(任意类型)。iter的初值指向vector对象的首元素。双冒号(::)表示此iterator(泛型指针)是位于elemType类型的vector
定义内的嵌套类型
注意:vector<>前加个typename,是因为在模板函数里定义的泛型指针要满足这个格式
void display(const vector<elemType>&vec,ostream &os=cout)
这一行我提供了默认参数值,让输出默认输出到屏幕中去
for(;iter!=end_it;++iter)
{
os<<*iter<<' ';
}
os<<endl;
这个就是遍历vector对象让vector对象的所有元素都显示下。注意,display()函数只可用于vector,不要用于list,我也不知道怎么用于list,再说吧。
我说明几个要点:
想通过iterator(泛型指针)取得元素值,可以采用一般指针的提领方式,举个例子,假如我定义了个泛型指针iter,*iter即课提领iter指针来取得iter指针指向的对象的元素值。
如果想用泛型指针调用底部的string元素(类型的对象)所提供的操作(比如.size(),.length()等),
用"->"箭头运算符:(假如我定义了个泛型指针iter)
vector<string>cs_vec;
vector<string>::const_iterator iter=cs_vec.begin();//泛型指针定义并初始化为指向string类型vector对象的首元素
cout<<"string value of elemnt:"<<*iter;//泛型指针提领操作获得其指向的对象的值
cout<<"("<<iter->size()<<"):"<<*iter<<endl;//相当于cs_vec[0].size()(打个比方)
//并且cs_vec[0]是个string类型的字符串。
template<typename IteratorType,typename elemType>IteratorType find(IteratorType first,IteratorType last,const elemType &value)
{
for(;first!=last;++first)
{
if(value==*first)
{
return first;
}
}
return last;//走到这里证明没找到和value一样的元素,直接返回last指针。。。
}
这是重要的find()函数,我将其定义为模板函数,然后模板函数涉及到两个模板类型。first和last形参都是泛型指针,value是引用型形参。然后实现和3.1中的find()函数差不多,区别是底下返回last,你要是array/vector/list是个空的话last=0,此时就相当于return 0了。
int main()
{
const int asize=8;//用泛型指针作为形参的find()来处理array、vector和list
int ia[asize]={1,1,2,3,5,8,13,21};
vector<int> ivec(ia,ia+asize);//容器被赋初值
list<int> ilist(ia,ia+asize);//容器被赋初值
display(ivec);
int *pia=find(ia,ia+asize,5);
if(pia!=ia+asize)//这里对应着return last,在传参的时候last=ia+asize
{
//走进了if,证明在容器里找到了指定元素
cout<<"*pia:"<<*pia<<endl;
}
vector<int>::iterator it;//定义泛型指针
it=find(ivec.begin(),ivec.end(),14);//注意这个;要写上//find()函数传入容器的泛型算法
if(it!=ivec.end())
{
//走进了if,证明找到了指定元素
cout<<"*it:"<<*it<<endl;
}
list<int>::iterator iter;//定义泛型指针
iter=find(ilist.begin(),ilist.end(),21);
if(iter!=ilist.end())
{
cout<<"*iter:"<<*iter<<endl;
}
//若都没找到就什么也不做
return 0;
}
然后就是咱大名鼎鼎的main()函数了用来验证泛型指针的作用,如果find()返回0,证明未找到和value对应的元素,则cout上什么也不输出。为什么学习泛型指针,原因就是泛型指针可以让我们免去定义一个针对vector的指针、定义一个针对list的指针、针对array的指针,省工作量。
附一张程序运行结果吧(我遍历了vector对象。中间的it泛型指针指向了0(NULL),证明没在vector对象(ivec)中找到元素,所以到了对应的cout那里就什么也不输出给屏幕。)
程序0错误0警告