STL之list模拟实现(反向迭代器讲解以及迭代器失效)

这次是关于list的模拟实现的代码,先看看下面的代码:

cpp 复制代码
#pragma once
#include <iostream>
#include "reve_iterator.hpp"
using namespace std;
namespace cc
{
 //链表节点
 template<class T>
 struct ListNode
 {
    T _val;
    ListNode *_next;
    ListNode *_prev;
    ListNode(const T& x=T())
        : _val(x)
        , _next(nullptr)
        , _prev(nullptr)
    {}
 }; 
 //迭代器
 template<class T,class ref,class ptr>
 struct list_iterator
 {
    typedef ListNode<T> Node;
    typedef list_iterator<T,ref,ptr> iterator;
    list_iterator(Node *node)
        : _node(node)
    {}
    iterator& operator++()
    {
        _node=_node->_next;
        return *this;
    }
    iterator operator++(int)
    {
        iterator tem(_node);
        _node=_node->_next;
        return tem;
    }
    iterator& operator++()const
    {
        _node=_node->_next;
        return *this;
    }
    iterator operator++(int)const
    {
        iterator tem(_node);
        _node=_node->_next;
        return tem;
    }
    iterator& operator--()
    {
        _node=_node->_prev;
        return *this;
    }
    iterator operator--(int)
    {
        iterator tem(_node);
        _node=_node->_prev;
        return tem;
    }
    bool operator!=(const iterator& d)const
    {
        return _node!=d._node;
    }
    ref operator*()const
    {
        return _node->_val;
    }
    ptr operator->()const
    {
        return &(_node->_val);
    }
    Node *_node;
 };
 //链表
 template<class T>
 class List
 {
public:
    typedef ListNode<T> Node;
    typedef list_iterator<T,T&,T*> iterator;
    typedef list_iterator<T,const T&,const T*> const_iterator;
    typedef reve_iterator<iterator,T&,T*> riterator;
    typedef reve_iterator<iterator,const T&,const T*> const_riterator;
    void init()
    {
        _head->_next=_head;
        _head->_prev=_head;
    }
    List()
        : _head(new Node)
    {
        _head->_next=_head;
        _head->_prev=_head;
    }
    template<typename Iterator>
    List(Iterator begin,Iterator end)
        : _head(new Node)
    {
        init();
        while(begin!=end)
        {
            push_back(*begin);
            begin++;
        }
    }
    List(const List<T>& d)
        : _head(nullptr)
    {
        List<T> tem(d.begin(),d.end());
        swap(tem);
    }
    List<T>& operator=(List<T> d)
    {
        swap(d);
        return *this;
    }
    iterator begin()
    {
        return iterator(_head->_next);
    }
    iterator end()
    {
        return iterator(_head);
    }
    riterator rbegin()
    {
        return riterator(_head);
    }
    riterator rend()
    {
        return riterator(_head->_next);
    }
    const_iterator begin()const
    {
        return const_iterator(_head->_next);
    }
    const_iterator end()const
    {
        return const_iterator(_head);
    }
    void swap(List<T>& d)
    {
        std::swap(_head,d._head);
    }
    void push_back(const T& x=T())
    {
        Node *cur=new Node(x);
        Node *tail=_head->_prev;
        tail->_next=cur;
        cur->_prev=tail;
        cur->_next=_head;
        _head->_prev=cur;
    }
private:
    Node *_head;
 };
}

上面是list的代码,其底层是一个带头双向循环的链表,实现的方法就不说了,相信大家已经都会了,然后自己实心的list我没有写析构函数等,这个也很简单,循环利用成员函数中的删除函数就可以。

先来说说个人认为比较重要的东西:

首先是迭代器失效:list迭代器的失效与vector不同,list的迭代器在插入时不会有迭代器失效的现象,只有在删除的时候才有迭代器失效的现象,插入没有失效现象的原因,很简单,就不多说,而删除导致迭代器失效的原因是,在删除一个节点的时候,我们把这个节点所占的空间已经给释放了,所以此时指向这个节点的指针已经是野指针了,所以导致迭代器失效。

其次就是反向迭代器的实现了,我们先看看下面的反向迭代器的代码:

cpp 复制代码
#pragma once
#include "list.hpp"
namespace cc
{
    template<class Iterator,class ref,class ptr>
    struct reve_iterator
    {
    public:
        typedef reve_iterator<Iterator,ref,ptr> riterator;
        reve_iterator(Iterator it)
            : It(it)
        {}
        bool operator!=(const riterator& d)const
        {
            return It!=d.It;
        }
        riterator& operator++()
        {
            It--;
            return *this; 
        }
        riterator operator++(int)
        {
            Iterator tem(It);
            It--;
            return riterator(tem);
        }
        riterator& operator++()const
        {
            It--;
            return *this; 
        }
        riterator operator++(int)const
        {
            Iterator tem(It);
            It--;
            return riterator(tem);
        }
        ref operator*()const
        {
            Iterator tem(It);
            return *(--tem);
        }
        ptr operator->()const
        {
            return &(*It);
        }
    private:
        Iterator It;
    };
}

以上就是反向迭代器实现的代码,在list中的迭代器,不像我们之前的迭代器是原生指针,list的迭代是我们的自己定义的类似于一个指针的类,个人理解其实就是指针,只不过这个指针被包装了,我们以前用的指针没有被包装而已。那就来说说实现方法吧。首先就是这个指针类的成员函数了,运算符的重载一定要有,具体的看上面代码。主要讲解的是,因为反向迭代器的实现底层是在正向迭代器的基础上实现的,所以反向迭代中的++对于正向迭代器来说,就是--,一定要区分开这个。再就是"->"的重载其实是为了以防万一,防止val的值是一种类,这样的话就可以访问这个类的值了。

以上就是本篇的内容,如果对你们有帮助的话,希望点一下赞!谢谢支持!

相关推荐
爱学习的张大12 分钟前
Windows 环境下安装 OmniParser
windows
Tim_1019 分钟前
【C++入门】04、C++浮点型
开发语言·c++
hkNaruto27 分钟前
【C++】记录一次C++程序编译缓慢原因分析——滥用stdafx.h公共头文件
开发语言·c++
石像鬼₧魂石1 小时前
HexStrike AI 理想操作流程清单(完整功能版)
linux·人工智能·windows·学习·ubuntu
柏木乃一1 小时前
进程(6)进程切换,Linux中的进程组织,Linux进程调度算法
linux·服务器·c++·算法·架构·操作系统
Trouvaille ~1 小时前
【Linux】从磁盘到文件系统:深入理解Ext2文件系统
linux·运维·网络·c++·磁盘·文件系统·inode
xwill*1 小时前
python 字符串拼接
linux·windows·python
我是苏苏2 小时前
Web开发:Windows系统中使用GUI界面或cmd命令设置防火墙规则
windows
superman超哥2 小时前
仓颉锁竞争优化深度解析
c语言·开发语言·c++·python·仓颉
charlie1145141912 小时前
快速在WSL上开发一般的C++上位机程序
开发语言·c++·笔记·学习·环境配置·工程