这次是关于list的模拟实现的代码,先看看下面的代码:
#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的迭代器在插入时不会有迭代器失效的现象,只有在删除的时候才有迭代器失效的现象,插入没有失效现象的原因,很简单,就不多说,而删除导致迭代器失效的原因是,在删除一个节点的时候,我们把这个节点所占的空间已经给释放了,所以此时指向这个节点的指针已经是野指针了,所以导致迭代器失效。
其次就是反向迭代器的实现了,我们先看看下面的反向迭代器的代码:
#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的值是一种类,这样的话就可以访问这个类的值了。文章来源:https://www.toymoban.com/news/detail-672950.html
以上就是本篇的内容,如果对你们有帮助的话,希望点一下赞!谢谢支持!文章来源地址https://www.toymoban.com/news/detail-672950.html
到了这里,关于STL之list模拟实现(反向迭代器讲解以及迭代器失效)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!