反向迭代器的实现
反向迭代器介绍
反向迭代器和正向迭代器的区别就是
反向迭代器的++/--是倒着走!
那么反向迭代器的本质是什么?——==是一个容器适配器!==
本质就是通过==封装迭代器==,来让其实现我们想要的行为!
也可以通过通过复制一份正向迭代器,然后修改正向迭代器的行为,来实现反向迭代器,但是这样子很麻烦,没有很好的复用代码!
反向迭代器模板的实现
我们可以先看看STL库里面的list中的反向迭代器
==我们可以看到STL库里面的list的反向迭代器本质就是使用正向迭代器封装出来的!==
我们可以发现所谓的反向迭代器就是将在使用++的时候去调用正向的--
使用--去调用正向的++
而且其实所谓的反向迭代器不是一个每一个类都单独设计的!而是用的都是同一份的模板!
==只要任何一个类的迭代器作为模板参数给这个容器适配器!那么就可以转化为那个类的反向迭代器!==——完成了代码的复用!
成员函数和模板参数
namespace MySTL
{
template<class InputIterator,class Ref,class Ptr>
class reverse_iterator
{
public:
typedef reverse_iterator<InputIterator,Ref,Ptr> self;
private:
InputIterator _it;
};
}
构造函数
namespace MySTL
{
template<class InputIterator,class Ref,class Ptr>
class reverse_iterator
{
public:
typedef reverse_iterator<InputIterator,Ref,Ptr> self;
reverse_iterator(InputIterator it)
:_it(it)
{}//构造函数
private:
InputIterator _it;
};
}
operator*()——解引用重载
namespace MySTL
{
template<class InputIterator,class Ref,class Ptr>
class reverse_iterator
{
public:
typedef reverse_iterator<InputIterator,Ref,Ptr> self;
Ref operator*()const
{
InputIterator tmp = _it;
return *(--tmp);
}
private:
InputIterator _it;
};
}
为什么要怎么写?==我们发现反向迭代器解引用不是取得现在迭代器的数据,而是取得前面的迭代器的数据!==
==这样我们就很好理解为什么了!要得到的是现在迭代器的前一个迭代器的数据!==
==end(),我们一开始就是指是最后一个元素的下一个!rend也依旧保留了这个概念!,begin()是指第一个元素!那么rbegin也是同理保留了这个概念!==
==因为rend()是begin()封装的,rbegin()是end()封装的! ,只有先去 -- 这样子rend()与rbegin(),才能符合我们一般理解的逻辑!不然rbegin()就是第一个元素的前一个,rend()就是最后一个元素!==
operator-> 重载
namespace MySTL
{
template<class InputIterator,class Ref,class Ptr>
class reverse_iterator
{
public:
typedef reverse_iterator<InputIterator,Ref,Ptr> self;
Ptr operator->()const
{
return &(operator*());
}
//-> 重载返回的是数据的地址!所以我们可以简单调用一下operator*!
private:
InputIterator _it;
};
}
==->重载返回的是该数据的地址!我们可以直接调用operator*()!因为解引用重载返回的是该数据的引用!然后我们在此基础上取地址!就可以得得到该数据的地址!==
operator++(前置)
namespace MySTL
{
template<class InputIterator,class Ref,class Ptr>
class reverse_iterator
{
public:
typedef reverse_iterator<InputIterator,Ref,Ptr> self;
self& operator++()
{
--_it;
return *this;
}
private:
InputIterator _it;
};
}
==反向迭代器中的++,就是正向的--
operator--(前置)
namespace MySTL
{
template<class InputIterator,class Ref,class Ptr>
class reverse_iterator
{
public:
typedef reverse_iterator<InputIterator,Ref,Ptr> self;
self& operator--()
{
++_it;
return *this;
}
private:
InputIterator _it;
};
}
operator++(后置)
namespace MySTL
{
template<class InputIterator,class Ref,class Ptr>
class reverse_iterator
{
public:
typedef reverse_iterator<InputIterator,Ref,Ptr> self;
self operator--(int)
{
self temp = _it;
++_it;
return temp;
}
private:
InputIterator _it;
};
}
后置++,是先用后加,是传值返回,返回的是现在这个迭代器的值
operator--(后置)
namespace MySTL
{
template<class InputIterator,class Ref,class Ptr>
class reverse_iterator
{
public:
typedef reverse_iterator<InputIterator,Ref,Ptr> self;
self operator--(int)
{
self temp = _it;
++_it;
return temp;
}
private:
InputIterator _it;
};
}
后置--和后置++同理
operator!=
namespace MySTL
{
template<class InputIterator,class Ref,class Ptr>
class reverse_iterator
{
public:
typedef reverse_iterator<InputIterator,Ref,Ptr> self;
bool operator!= (const self& s)const
{
return _it != s._it;
}
private:
InputIterator _it;
};
}
记住一点!==迭代器想不相同看到是内容相不相同!而不是看迭代器本身的地址相不相同!==
全部代码
namespace MySTL
{
template<class InputIterator,class Ref,class Ptr>
class reverse_iterator
{
public:
typedef reverse_iterator<InputIterator,Ref,Ptr> self;
reverse_iterator(InputIterator it)
:_it(it)
{}
Ref operator*()const
{
InputIterator tmp = _it;
return *(--tmp);
}
Ptr operator->()const
{
return &(operator*());
}
//-> 重载返回的是数据的地址!所以我们可以简单调用一下operator*!
self& operator++()
{
--_it;
return *this;
}
self operator++(int)
{
self temp = _it;
--_it;
return temp;
}
self& operator--()
{
++_it;
return *this;
}
self operator--(int)
{
self temp = _it;
++_it;
return temp;
}
bool operator!= (const self& s)const
{
return _it != s._it;
}
private:
InputIterator _it;
};
}
list的反向迭代器实现
标签:const,迭代,iterator,STL,self,反向,operator,reverse From: https://blog.51cto.com/u_15835985/6457800namespace MySTL { //iterator类的实现,list_node类的实现 template<class T> class list { typedef list_node<T> node; private: node* _head; size_t _size; public: typedef __list_iterator<T,T&,T> iterator; typedef __list_iterator<T, const T&,const T*> const_iterator; typedef MySTL::reverse_iterator<iterator, T&, T*> reverse_iterator; typedef MySTL::reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator; //这里只列出rbegin与rend的实现 const_iterator begin()const { return const_iterator(_head->_next); } iterator end() { return iterator(_head); } const_iterator end()const { return const_iterator(_head); } //反向迭代器! reverse_iterator rend() { return reverse_iterator(begin()); } reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rend()const { return const_reverse_iterator(begin()); } const_reverse_iterator rbegin()const { return const_reverse_iterator(end()); } }; void testlist() { list<int> lt; lt.push_back(2); lt.push_back(5); lt.push_back(7); lt.push_back(1); list<int>::reverse_iterator rit = lt.rbegin(); while (rit != lt.rend()) { cout << *rit << " "; ++rit; } cout << endl; std::vector<int>v = {1, 343, 2, 8, 5, 9}; const list<int> lt2(v.begin(),v.end()); list<int>::const_reverse_iterator rit2 = lt2.rbegin(); while (rit2 != lt2.rend()) { cout << *rit2 << " "; ++rit2; } } }; //test.cpp #include"mystl_list.h" int main() { MySTL::testlist(); return 0; }
==我们可以直接去使用这个反向迭代器适配器来适配出各种自定义类型的反向迭代器!只要这个自定义类型支持迭代器!==
==无论是vector,deque,list都是通过这种方式来实现反向迭代器的!==