zoukankan      html  css  js  c++  java
  • STL——迭代器的概念

    迭代器是一种抽象的设计概念,现实程序语言中并没有直接对应于这个概念的实物。

    1 迭代器设计思维——STL关键所在

    不论是泛型思维或STL的实际运用,迭代器都扮演这重要的角色。STL的中心思想在于:将数据容器和算法分开,彼此独立设计,最后再以一贴胶着剂将它们撮合在一起。容器和算法的泛型化,从技术的角度来看是并不困难,C++的class template和function templates可分别达成目标。

    以下是容器、算法、迭代器的合作展示,以算法find()为例,它接受两个迭代器和一个”搜索目标“:

    template <class InputIterator,class T>
    InputIterator find(InputIterator first,InputIterator last,const T& value)
    {
        while(first=!last&&*first!=value)
           ++first;
        return first;
    }

    只要给出不同的迭代器,find()便能够对不同的容器进行直接操作:

    #include<vector>
    #include<list>
    #include<deque>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    int main()
    {
        const int arraySize=7;
        int ia[arraySize]={0,1,2,3,4,5,6};
        vector<int> ivect(ia,ia+arraySize);
        list<int> ilist(ia,ia+arraySize);
        deque<int> ideque(ia,ia+arraySize);
        //注意算法和成员方法的区别
        vector<int>::iterator it1=find(ivect.begin(),ivect.end(),4);
        if(it1!=ivect.end())
            cout<<"4 found. "<<*it1<<endl;
        else
            cout<<"4 not found."<<endl;
        list<int>::iterator it2=find(ilist.begin(),ilist.end(),6);
        if(it2==ilist.end())
            cout<<"6 not found. "<<endl;
        else
            cout<<"6 found. "<<*it2<<endl;
    
        deque<int>::iterator it3=find(ideque.begin(),ideque.end(),8);
        if(it3==ideque.end())
            cout<<"8 not found."<<endl;
        else
            cout<<"8 found. "<<*it3<<endl;
    }

    从上面的例子看来,迭代器似乎依附于在容器之下,是吗?有没有独立而泛用的迭代器?我们又该如何自行设计特殊的迭代器?

    2 迭代器是一种smart pointer

    迭代器是一种行为类似指针的对象,而指针的各种行为中最常见也最重要的便是内容提领(dereference)和成员访问(member access),因此,迭代器最重要的编程工作就是对operator*和oper->进行重载工作。关于这一点,C++标准库有一个auto_ptr可供我们参考。这是一个用来包含原生指针的对象,声名狼藉的内存泄露问题可借此获得解决。auto_ptr用法如下,和原生指针一模一样:

    void func()
    {
        auto_ptr<string> ps(new string("jjhou");
        cout<<*ps<<endl;
        cout<<ps->size()<<endl;
    //离开前不需要delete,auto_ptr会自动释放内存
    }

    函数第一行的意思是,以算式new 动态配置一个初值为"jjhou"的string对象,并将所得的结果(一个原生指针)作为auto_ptr<string> 对象的初值。注意,auto_ptr尖括号内放的是”原生指针所指对象“的型别,而不是原生指针的型别。

    auto_ptr的源代码在头文件<memory>中:

    //file:autoptr.cpp
    
    template<class T>
    class auto_ptr{
    public:
        explicit auto_ptr(T *p=0):pointee(p) {}
        template<class U>
        auto_ptr(auto_ptr<U>& rhs):pointee(rhs.release()) {}
        ~auto_ptr() {delete pointee;}
        
        template<class U>
        auto_ptr<T>& operator=(auto_ptr<U> &rhs)
        {
            if(this!=rhs) reset(ths.release());
            return *this;
        }
    
        T& operator*() const { return *pointee;}
        T* operator->() const { return pointee;}
        T* get() const {return pointee;}
        //...
    private:
        T *pointee;
    };

    有了模仿对象,现在我们来为list(链表)设计一个迭代器,假设list机器节点的结构如下:

  • 相关阅读:
    【LGR-070】洛谷 3 月月赛-官方题解
    洛谷P1034 矩形覆盖
    <C和指针---读书笔记9>
    <C和指针---读书笔记8>
    <C和指针---读书笔记7>
    <C和指针---读书笔记6>
    <C和指针---读书笔记1>
    <C和指针---读书笔记2>
    <C和指针---读书笔记5>
    <C和指针---读书笔记4>
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4162060.html
Copyright © 2011-2022 走看看