反向迭代器的模拟实现
- 一、反向迭代器的定义
- 二、反向迭代器的功能
- 2.1 operator++
- 2.2 operator- -
- 2.3 operator*
- 2.4 operator!=
- 三、list反向迭代器模拟实现完整代码
- 3.1 list.h
- 3.2 iterator.h
- 3.3 test.cpp
一、反向迭代器的定义
我们反向迭代器的思路是复用正向迭代器的功能,使用一个正向迭代器来创建一个反向迭代器,如果是vector的正向迭代器,创建的就是vector的反向迭代器,如果是list的正向迭代器,创建的就是list的反向迭代器。
我们之前实现普通迭代器是声明了一个迭代器类。此时,我们也要定义一个反向迭代器类。而这个反向迭代器是由正向迭代器构造而来的。
template<class Iterator,class Ref,class Ptr>
struct ReverseIterator
{typedef ReverseIterator<Iterator,Ref,Ptr> Self;Iterator _cur;ReverseIterator(Iterator it):_cur(it){}
};
在list类中,我们要重命名一个反向迭代器,并将其调用接口写好。其中关于模板参数的书写,我们要注意一下。
第一个模板参数是普通迭代器类型。
第二个是迭代器其指向其数据的数据类型的引用。
第三个是迭代器其指向其数据的数据类型的指针。
并在此基础上定义好const_iterator
typedef __list_iterator<T,T&,T*> iterator;
typedef __list_iterator<T,const T&,const T*> const_iterator;typedef ReverseIterator <iterator, T&, T*> reverse_iterator;
typedef ReverseIterator <iterator, const T&, const T*> const_reverse_iterator;
这样的好处是,调用普通的rbegin()则创建普通的反向迭代器,其中operator*的返回值是可修改的。
而const成员调用的是const类型rbegin(),则创建了const_iterator。
以下是list中通过普通迭代器构造出反向迭代器的rbegin()、rend()。
reverse_iterator rbegin()
{return reverse_iterator(end());
}reverse_iterator rend()
{return reverse_iterator(begin());
}
二、反向迭代器的功能
2.1 operator++
Self& operator++()
{--_cur;return *this;
}Self& operator++(int)
{Self& tmp(_cur);--_cur;return tmp;
}
2.2 operator- -
Self& operator--()
{++_cur;return *this;
}Self& operator--(int)
{Self& tmp(_cur);++_cur;return tmp;
}
2.3 operator*
这里先明确一点,在STL中,反向迭代器的rbegin()是由list的end()构造的,也就是_head结点。所以我们在解引用的时候,其实是返回其前一个位置的数据。这样做的好处是为了做到迭代器指向的对称。
Ref operator*()
{Iterator tmp = _cur;--tmp;return *tmp;
}
2.4 operator!=
bool operator!=(const Self& s)
{return _cur != s._cur;
}
三、list反向迭代器模拟实现完整代码
3.1 list.h
#pragma once
#include<assert.h>
#include"Iterator.h"namespace zl
{template<class T>struct list_node{list_node<T>* _next;list_node<T>* _prev;T _data;list_node(const T& x=T()):_next(nullptr),_prev(nullptr),_data(x){}};//1、迭代器要么就是原生指针//2、迭代器要么就是自定义类型对原生指针的封装,模拟指针的行为template<class T,class Ref,class Ptr>struct __list_iterator{typedef list_node<T> node;typedef __list_iterator<T,Ref,Ptr> self;node* _node;__list_iterator(node* n):_node(n){}Ref& operator*(){return _node->_data;}Ptr operator->() //it->_a1 it->->_a1 本来应该是两个->,但是为了增强可读性,省略了一个->{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& s){return _node != s._node;}bool operator==(const self& s){return _node == s._node;}};//template<class T, class Ref, class Ptr>//struct __list_reverse_iterator//{// typedef list_node<T> node;// typedef __list_reverse_iterator<T, Ref, Ptr> self;// node* _node;// __list_reverse_iterator(node* n)// :_node(n)// {}// Ref& operator*()// {// return _node->_data;// }// Ptr operator->() //it->_a1 it->->_a1 本来应该是两个->,但是为了增强可读性,省略了一个->// {// 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& s)// {// return _node != s._node;// }// bool operator==(const self& s)// {// return _node == s._node;// }//};/*template<class T>struct __list_const_iterator{typedef list_node<T> node;typedef __list_const_iterator<T> self;node* _node;__list_const_iterator(node* n):_node(n){}const 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& s){return _node != s._node;}bool operator==(const self& s){return _node == s._node;}};*/template<class T>class list{typedef list_node<T> node;public:typedef __list_iterator<T,T&,T*> iterator;typedef __list_iterator<T,const T&,const T*> const_iterator;//typedef __list_reverse_iterator<T, T&, T*> reverse_iterator;typedef ReverseIterator <iterator, T&, T*> reverse_iterator;typedef ReverseIterator <iterator, const T&, const T*> const_reverse_iterator;//typedef __list_const_iterator<T> const_iterator;/*reverse_iterator rbegin(){return reverse_iterator(_head->_prev);}reverse_iterator rend(){return reverse_iterator(_head);}*/reverse_iterator rbegin(){return reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}iterator begin(){//iterator it(_head->_next);//return it;return iterator(_head->_next);}const_iterator begin() const{//iterator it(_head->_next);//return it;return const_iterator(_head->_next);}iterator end(){//iterator it(_head);//return it;return iterator(_head);}const_iterator end() const{//iterator it(_head);//return it;return const_iterator(_head);}void empty_init(){_head = new node;_head->_next = _head;_head->_prev = _head;}list(){/*_head = new node;_head->_next = _head;_head->_prev = _head;*/empty_init();}template <class Iterator>list(Iterator first, Iterator last){empty_init();while (first != last){push_back(*first);++first;}}//lt2(lt1) 拷贝构造传统写法/*list(const list<T>& lt){empty_init();for (auto e : lt){push_back(e);}}*/void swap(list<T>& tmp){std::swap(_head, tmp._head);}//现代写法list(const list<T>& lt){empty_init();list<T> tmp(lt.begin(), lt.end());swap(tmp);}//lt1=lt3list<T>& operator=(list<T> lt){swap(lt);return *this;}~list(){clear();delete _head;_head = nullptr;}void clear(){iterator it = begin();while (it != end()){//it = erase(it);erase(it++);}}void push_back(const T& x=T()){/*node* tail = _head->_prev;node* new_node = new node(x);tail->_next = new_node;new_node->_prev = tail;new_node->_next = _head;_head->_prev = new_node;*/insert(end(), x);}void push_front(const T& x = T()){insert(begin(), x);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}void insert(iterator pos, const T& x){node* cur = pos._node;node* prev = cur->_prev;node* new_node = new node(x);prev->_next = new_node;new_node->_prev = prev;new_node->_next = cur;cur->_prev = new_node;}iterator erase(iterator pos){assert(pos != end());node* prev = pos._node->_prev;node* next = pos._node->_next;prev->_next = next;next->_prev = prev;delete pos._node;return iterator(next);}private:node* _head;};void print_list(const list<int>& lt){list<int>::const_iterator it = lt.begin();while (it != lt.end()){//(*it) *= 2;cout << *it << " ";++it;}cout << endl;}void test_list1(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;for (auto e : lt){cout << e << " ";}cout << endl;print_list(lt);}struct AA{int _a1;int _a2;AA(int a1=0,int a2=0):_a1(a1),_a2(a2){}};void test_list2(){list<AA> lt;lt.push_back(AA(1, 1));lt.push_back(AA(2, 2));lt.push_back(AA(3, 3));//AA* ptrlist<AA>::iterator it = lt.begin();while (it != lt.end()){//cout << (*it)._a1 << (*it)._a2 << endl;cout << it->_a1 << it->_a2 << endl;//cout << it.operator->()->_a1 << ":" << it.operator->()->_a1 << endl;++it;}cout << endl;}void test_list3(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);for (auto e : lt){cout << e << " ";}cout << endl;auto pos = lt.begin();++pos;lt.insert(pos, 20);for (auto e : lt){cout << e << " ";}cout << endl;lt.push_back(100);lt.push_front(1000);for (auto e : lt){cout << e << " ";}cout << endl;lt.pop_back();lt.pop_front();for (auto e : lt){cout << e << " ";}cout << endl;}void test_list4(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);for (auto e : lt){cout << e << " ";}cout << endl;lt.clear();for (auto e : lt){cout << e << " ";}cout << endl;lt.push_back(10);lt.push_back(20);lt.push_back(30);lt.push_back(40);for (auto e : lt){cout << e << " ";}cout << endl;}void test_list5(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);for (auto e : lt){cout << e << " ";}cout << endl;list<int> lt2(lt);for (auto e : lt2){cout << e << " ";}cout << endl;list<int> lt3;lt3.push_back(10);lt3.push_back(20);lt3.push_back(30);lt3.push_back(40);lt3.push_back(50);for (auto e : lt3){cout << e << " ";}cout << endl;lt = lt3;for (auto e : lt){cout << e << " ";}cout << endl;}void test_list6(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;list<int>::reverse_iterator rit = lt.rbegin();while (rit != lt.rend()){cout << *rit << " ";++rit;}cout << endl;}}
3.2 iterator.h
#pragma oncenamespace zl
{//vector::iterator//list::iterator//deque::iteratortemplate<class Iterator,class Ref,class Ptr>struct ReverseIterator{typedef ReverseIterator<Iterator,Ref,Ptr> Self;Iterator _cur;ReverseIterator(Iterator it):_cur(it){}Ref operator*(){Iterator tmp = _cur;--tmp;return *tmp;}Self& operator++(){--_cur;return *this;}Self& operator--(){++_cur;return *this;}bool operator!=(const Self& s){return _cur != s._cur;}};
}
3.3 test.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
#include<list>
#include <functional>
#include<algorithm>
#include<string>
using namespace std;
#include "list.h"
#include"Iterator.h"
#include"vector.h"int main()
{//zl::test_list1();//zl::test_list2();//zl::test_list3();//zl::test_list4();//zl::test_list5();zl::test_list6();//zl::test_vector8();//std::vector<int>::iterator it;//cout << typeid(it).name() << endl;return 0;
}