1、目的:学习迭代器的封装,提高代码能力。

为实现list我们需要在头文件下实现三个大类,进行代码的控制与运行

头文件:

#include<iostream>

using namespace std;

#include<assert.h>

#include<algorithm>

基本结构:

basic—list模拟实现_list

2、list节点控制

basic—list模拟实现_迭代器_02

利用函数模板以针对所有类型

3、list功能控制

//list类
template<class T>
class list
{
    typedef ListNode<T> Node;

public:
//使用多个模板参数解决代码冗余问题
    typedef ListIterator<T, T&, T*> iterator;
    typedef ListIterator< T, const T&, const T&> const_iterator;
    typedef Reverse_iterator<T, T&, T*> reverse_iterator;
    typedef Reverse_iterator<  T, const T&, const T*> reverse_const_iterator;
    //创建头结点(哨兵位)
    void init()//多个函数均使用单独建立创建哨兵位的函数
    {
        _head = new Node();
        _head->_next = _head;
        _head->_prev = _head;
    }
    //构造
    list()
    {
        //创建头结点(哨兵位)
        /*_head = new Node();
        _head->_next = _head;
        _head->_prev = _head;*/

         init();
    }
    //n个val拷贝构造
    //建立头节点后直接尾插
    list(int n, const T& value = T())
    {
        init();
        while (n--)
        {
            push_back(value);
        }
    }
    //迭代器区间初始化
    template <class Iterator>
    list(Iterator first, Iterator last)
    {
        init();
        while (first != last)
        {
            push_back(*first);
            first++;
        }
    }

    //拷贝构造
    list(const list<T>& l)
    {
        /*_head = new Node();
        _head->_next = _head;
        _head->_prev = _head;*/
        init();

        for (auto& e : l)
        {
            push_back(e);
        }
    }
    list<T>& operator=(const list<T> lt)
    {
        swap(lt._head, _head);
        return *this;
    }

    //析构
    ~list()
    {
        clear();
        delete _head;
        _head = nullptr;
    }
    //清除数据
    void clear()
    {
        auto it = begin();
        while (it != end())
        {
            it = erase(it);
        }
    }

    //访问头,尾数据
    T& front()
    {
        return _head->_next->_data;
    }
    const T& front()const
    {
        return _head->_next->_data;
    }
    T& back()
    {
        return _head->_prev->_data;
    }
    const T& back()const
    {
        return _head->_prev->_data;
    }

    //迭代器

    iterator begin()
    {
        return iterator(_head->_next);
    }
    iterator end()
    {
        return iterator(_head);
    }
    const_iterator begin()const
    {
        return  const_iterator(_head->_next);

    }
    const_iterator end()const
    {
        return const_iterator(_head);

    }

    reverse_iterator rbegin()
    {
        return (--end());//_head->_prev
    }
    reverse_iterator rend()
    {
        return (end());//_head
    }
    reverse_const_iterator rbegin()const
    {
        return (--end());//_head->_prev
    }
    reverse_const_iterator rend()const
    {
        return (end());//_head
    }

    size_t size()const
    {
        size_t t = 0;
        list<T>::iterator it = begin();
        while (it != end())
        {
            t++;
            it++;
        }
        return it;
    }
    bool empty()const
    {
        return (size() != 0);
    }

    //插入与删除

    //尾插
    void push_back(const T& val)
    {
        insert(end(), val);
    }

    //尾删
    void pop_back()
    {
        erase(--end());
    }

    //头插
    void push_front(const T& val)
    {
        insert(begin(), val);
    }

    //头删
    void pop_front()
    {
        erase(begin());
    }

    // 在pos位置前插入值为val的节点,没有迭代器失效
    iterator insert(iterator pos, const T& val)
    {
        Node* cur = pos._node;
        Node* newnode = new Node(val);
        Node* prev = cur-> _prev;

        prev->_next = newnode;
        newnode->_prev = prev;
        newnode->_next = cur;
        cur->_prev =  newnode;
        return iterator(newnode);
    }

    // 删除pos位置的节点,返回该节点的下一个位置
    iterator erase(iterator pos)
    {
        assert(pos != end());
        Node* cur = pos._node;
        Node* prev = cur->_prev;
        Node* next = cur->_next;

        prev->_next = next;
        next->_prev = prev;

        delete cur;

        return iterator(next);
    }

    void swap(list<T>& lt)
    {
        std::swap(lt._head, _head);
    }

private:
    Node* _head;
};

4、迭代器控制

//List的迭代器类
//迭代器
//这里设计模板参数除了迭代器,还有Ref(引用)和Ptr(指针)
//这样设计是为了同时生成普通迭代器和const对象的迭代器
//普通对象(可读可写):iterator<T, T&, T*>
//const对象(可读不可写):const_iterator<T, const T&, const T*>
template<class T, class Ref, class Ptr>
struct ListIterator
{
    typedef ListNode<T> Node;
    typedef ListIterator<T, Ref, Ptr> Self;//设置多个模板使const与非const代码不冗余

    Node* _node;//相当于类下的private
    //拷贝构造
    ListIterator(Node* node)
        :_node(node)
    {}
    //重载解引用
    T& operator*()
    {
        return _node->_data;
    }
    //重载访问,取得解引用后的地址
    T* operator->()
    {
        return &_node->_data;
    }
    //重载前置++
    Self& operator++()
    {
        _node = _node->_next;
        return *this;
    }
    //重载后置++
    Self operator++(int)
    {
        Self tmp(*this);//返回临时对象不能用传引用返回,会造成非法访问
        _node = _node->_next;
        return tmp;
    }
    //重载前置--
    Self& operator--()
    {
        _node = _node->_prev;
        return *this;
    }
    //重载后置--
    Self operator--(int)
    {
        Self tmp(*this);//返回临时对象不能用传引用返回,会造成非法访问
        _node = _node->_prev;
        return tmp;
    }
    //重载!=
    bool operator!=(const Self& lt)
    {
        return lt._node != _node;
    }
    //重载==
    bool operator==(const Self& lt)
    {
        return lt._node == _node;
    }
};
//反向迭代器
//反向迭代器需要进行封装,其实就是复用普通迭代器,然后++和--操作反过来
//普通对象(可读可写):Reverse_iterator<iterator,T&,T*>
//const对象(可读不可写):Reverse_iterator<const_iterator,const T&,const T*>
template<class T, class Ref, class Ptr>
struct Reverse_iterator
{
    typedef ListNode<T> Node;
    typedef Reverse_iterator<T, Ref, Ptr> Self;
    Node* _node;
    Reverse_iterator(Node* node)
        :_node(node)
    {}
    //重载解引用
    T& operator*()
    {
        return _node->_data;
    }
    //重载访问,取得解引用后的地址
    T* operator->()
    {
        return &_node->_data;
    }
    //重载前置++
    Self& operator++()
    {
        _node = _node->prev;
        return *this;
    }
    //重载后置++
    Self operator++(int)
    {
        Self tmp(*this);//返回临时对象不能用传引用返回,会造成非法访问
        _node = _node->_prev;
        return tmp;
    }
    //重载前置--
    Self& operator--()
    {
        _node = _node->_next;
        return *this;
    }
    //重载后置--
    Self operator--(int)
    {
        Self tmp(*this);//返回临时对象不能用传引用返回,会造成非法访问
        _node = _node->_next;
        return tmp;
    }
    //重载!=
    bool operator!=(const Self& lt)
    {
        return lt._node != _node;
    }
    //重载==
    bool operator==(const Self& lt)
    {
        return lt._node == _node;
    }
};