Bootstrap

List迭代器的理解

List迭代器的理解

1.什么是list迭代器?

list迭代器其实就是一个迭代器指针,只不过这个迭代器是经过封装的对象,使得它可以满足list容器中节点的迭代器功能

2.为什么要有list迭代器?

list是一个双向带头的链表结构,普通的指针不能够让他随意的进行++ – *等操作,因此这些功能只能够自己封装成一个迭代器对象进行使用。

3.如何构建list迭代器

  • 1.构建list节点
template <class T>
    struct ListNode
    {
        ListNode(const T& _data=T())
            :prev(nullptr),
        next(nullptr),
        data(_data)
        {}

        ListNode<T>* prev;
        ListNode<T>* next;
        T data;
    };
  • 2.构建初代迭代器
template<class T>
    class list_iterator
    {
        typedef list_iterator<T>* pNode;
        typedef list_iterator<T> self;
    public:
        list_iterator(pNode _pointer)
            :pointer(_pointer)
            {}
        list_iterator(const self& l)
            pointer(l.pointer)
        {}
        T& operator*()
        {
            return pointer->data;
        }
        T* operator->()
        {
            return &(pointer->data);
        }
        self& operator++()
        {
            pointer = pointer->next;
            return pointer;
        }
        self operator++(int)
        {
            self tmp(*this);
            pointer = pointer->next;
            return tmp;
        }
        self& operator--()
        {
            pointer = pointer->prev;
            return pointer;
        }
        self operator--(int)
        {
            self tmp(*this);
            pointer = pointer->prev;
            return tmp;
        }
        bool operator==(self& l)
        {
            return pointer == l.pointer;
        }
        bool operator!=(self& l)
        {
            return pointer == l.pointer;
        }
    private:
        pNode pointer;
    };

4.list自带指针与构造迭代器的区别

//自带指针
ListNode* l1;
//构造的迭代器
list_iterator<T> l1;
  • 两者之间都是指针,因此都是占据4个字节
  • 不同的是,l1就是单纯的指针,不够通过*找到data值,同时不能够++或者–的操作。但是与l1不同,l2在l1的指针基础之上有进行了一系列运算符的重载,使得它有了许多新的功能,让他具备了迭代器的功能

5.更新版的迭代器

为了让list迭代器更加的灵活使用,可以将上面的迭代器做一个扩充版

typedef list_iterator<T,Ref,Ptr>* pNode;
typedef list_iterator<T,Ref,Ptr> self;

这样当我们需要做一个const的迭代器时,就可以不用写多份代码,使得代码冗余.

当我们需要普通版本的迭代器时就可以传入

typedef list_iterator<T,T&,T*> self;

当我们需要const版本的时候就可以传入

typedef list_iterator<T,const T&,const T*> self;

6.特殊迭代器函数的介绍

T*operator->()
{
    return &(pointer->data);
}

在这里插入图片描述

  • 上面的->这里需要注意,为了保证可读性,编译器在此处进行了优化,后面所有的类型在进行重载->时,都会进行省略。
;