STL源码剖析读书笔记6

来源:互联网 发布:英语网络课程推荐 编辑:程序博客网 时间:2024/05/22 13:36

迭代器设计思维初步

iterator的定义如下:提供一种方法,使之能够依序寻访某个聚合物所含的各个元素,而又无需暴露该聚合物内部的表述方法。STL的中心思想就是容器和算法分开独立设计,然后再以一个粘合剂胶着起来。
迭代器是一种智能指针,它最重要的工作就是对operator*和opertor->进行重载。在对迭代器实现的过程中不可避免的就要暴露所指容器的实现细节,因此每一种STL容器都有一个专属的迭代器。

//这里贴出智能指针的源码<code class="hljs cpp">template<class t="">class auto_ptr{private:    T*ap;public:    //constructor & destructor-----------------------------------(1)    explicit auto_ptr(T*ptr=0)throw():ap(ptr) {}    ~auto_ptr()throw() {        delete ap;    }    //Copy & assignment--------------------------------------------(2)    auto_ptr(auto_ptr& rhs)throw():ap(rhs.release()) {}    template<class y="">    auto_ptr(auto_ptr<y>&rhs)throw():ap(rhs.release()) {}    auto_ptr& operator=(auto_ptr&rhs)throw()    {        reset(rhs.release());        return *this;    }    template<class y="">    auto_ptr& operator=(auto_ptr<y>&rhs)throw()    {        reset(rhs.release());        return *this;    }    //Dereference----------------------------------------------------(3)    T& operator*()const throw()    {        return *ap;    T* operator->()const throw()    {        return ap;    }    //Helper functions------------------------------------------------(4)    //value access    T* get()const throw()    {        return ap;    }    //release owner ship    T* release()throw()    {        T* tmp(ap);        ap = 0;        return tmp;    }    //reset value    void reset(T* ptr = 0)throw()    {        if(ap != ptr)        {               //我们在删除一个指针之后,编译器只会            //释放该指针所指向的内存空间,而不会删除这个指针本身            delete ap;            ap = ptr;        }    }    //Special conversions-----------------------------------------------(5)    template<class y="">    struct auto_ptr_ref    {        Y*yp;        auto_ptr_ref(Y*rhs):yp(rhs){}    };    auto_ptr(auto_ptr_ref<t>rhs)throw():ap(rhs.yp) {}    auto_ptr& operator=(auto_ptr_ref<t>rhs)throw()    {        reset(rhs.yp);        return*this;    }    template<class y="">    operator auto_ptr_ref<y>()throw()    {        return auto_ptr_ref<y>(release());    }    template<class y="">    operator auto_ptr<y>()throw()    {        return auto_ptr<y>(release());    }};

下面我们自己写个简单的容器迭代器雏形,为的是引出接下来要讲的内容:

//全局重载尽量少用,多使用友元函数与成员函数,毕竟比较操作一般情况下都需要访问类的私有成员。//常用的规则是:对于算术操作符(+ - * / %等)重载函数通常使用友元函数,而复合操作符(+= -= <= ==等)通常使用成员函数。//单向链表template<typename T>class List{      pubic:      List& push_front(T value);      //省略一部分功能,你们都懂得      private:      MyList<T>* _front;      MyList<T>* _end;      long   _size;}template<typename T>class MyList{      pubic:      MyList* next()const;      private:      T _value;      MyList* _next;}template<class Item>struct ListIterator{      Item* ap;      ListIterator(Item* p=0): ap(p){}      Item& operator*()const{         return *ap;      }      Item* operator->()const{         return ap;      }      ListIterator& operator++(){                    ap = ap->next();                    return *this;      }      ListIterator operator++(int){                   ListIterator  old = *this;                   ++(*this);                   return old;      }      bool operator==(ListIterator& rhs)const{           return rhs.ap == ap;      }      bool operator!=(ListIterator& rhs)const{           return rhs.ap != ap;      }}//全局的operator!=template<typename T>bool operator!=(MyList<T>& rhs,T& value){     return rhs.value() != value;}

迭代器相应型别

  1. 可行的方法:函数模板的参数推导

    C++只支持sizeof,没有typeof,即便用了RTTI的typeid,只是获得型别名称,却不能拿来声明变量。

    这里写图片描述

原创粉丝点击