Essential C++学习记录&笔记整理17(了解Iterator(泛型指针))

这节第一次看自闭了 ,又看了一遍,照书上代码敲了敲补充了下细节,才算明白。

了解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警告

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值