摘要:vector 和 list 反向迭代器实现
前言:Iterator 的意义在于封装屏蔽底层,实现的复杂细节用统一简单的方式访问容器。其底层可能是原生指针,也可能不是。例如 vector 模拟实现中 iterator 的底层实现就是一个指针,而 list 的模拟实现中的 iterator 是一个自定义类型。
// 将以下代码适配到vector和list中做反向迭代器,理解反向迭代器的原理 namespace Btl { // 适配器 -- 复用 template<class Iterator, class Ref, class Ptr> struct Reverse_iterator { Iterator _it; }; // vector和list反向迭代器实现 }
整体架构的思路:复用 Iterator 来封装 Reverse_Iterator
1. Reverse_Iterator 基本成员函数
反向迭代器需要实现的基本成员函数同普通迭代器一样,而实现思路也大差不差。只是要注意,反向迭代器的成员变量就是一个 iterator,因此函数实现即复用 iterator 的成员函数即可。
个别成员函数提醒:
operator->() 这个函数本质上就是对 operator*() 的结果取地址,所以这里可以复用 operator*() 写成 &(operator*()),也可以选择复用 Iterator 的operator->() 函数写成 it.operator->()
namespace Btl
{
// 适配器 -- 复用
template<class Iterator, class Ref, class Ptr>
struct Reverse_iterator
{
typedef Reverse_iterator<Iterator, Ref, Ptr> Self;
Iterator _it;
Ref operator*()
{
return *it;
}
Ptr operator->()
{
return &(operator*());//return it.operator->()
}
Self& operator++()
{
--_it;
return *this;
}
Self& operator--()
{
++_it;
return *this;
}
Self operator++(int)
{
Self tmp = _it;
--_it;
return tmp;
}
Self operator--(int)
{
Self tmp = _it;
++_it;
return tmp;
}
bool operator!=(const Self& s)
{
return _it != s._it;
}
bool operator==(const Self& s)
{
return _it == s._it;
}
};
}
2. list 的 Reverse_Iterator
(list 的成员变量和其他成员函数在此处省略不展示,该部分具体内容请参考 “ list 的模拟实现 ”一文,此处仅展示其迭代器的实现)
从上图中不难看出 rbegin = --end ,rend = --begin (rend = end 这样写也可以).(ps.这不是正确的写法,只是表达这样的意思)
namespace Btl
{
// List的节点类
template<class T>
struct ListNode
{
ListNode(const T& val = T())
: _val(val)
, _pPre(nullptr)
, _pNext(nullptr)
{}
ListNode<T>* _pPre;
ListNode<T>* _pNext;
T _val;
};
//List的迭代器类
template<class T, class Ref, class Ptr>
class ListIterator
{
typedef ListNode<T>* PNode;
typedef ListIterator<T, Ref, Ptr> Self;
public:
//constructor
ListIterator(PNode pNode = nullptr)
:_pNode(pNode)
{}
ListIterator(const Self& l)//copy constructor
{
_pNode = l._pNode;
}
//operations
Ref operator*()
{
return _pNode->_val;
}
Ptr operator->()
{
return &_pNode->_val;
}
Self& operator++()
{
_pNode = _pNode->_pNext;
return *this;
}
Self operator++(int)
{
Self tmp = _pNode;
_pNode = _pNode->_pNext;
return tmp;
}
Self& operator--()
{
_pNode = _pNode->_pPre;
return *this;
}
Self operator--(int)
{
Self tmp = _pNode;
_pNode = _pNode->_pPre;
return tmp;
}
bool operator!=(const Self& l)
{
return _pNode != l._pNode;
}
bool operator==(const Self& l)
{
return _pNode == l._pNode;
}
PNode _pNode;
};
//list类
template<class T>
class list
{
typedef ListNode<T> Node;
typedef Node* PNode;
public:
typedef ListIterator<T, T&, T*> iterator;
typedef ListIterator<T, const T&, const T&> const_iterator;
typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;
typedef Reverse_iterator<const_iterator, T&, T*> const_reverse_iterator;
///
// List Iterator
iterator begin()
{
return _pHead->_pNext;
}
iterator end()
{
return _pHead;
}
const_iterator begin() const
{
return _pHead->_pNext;
}
const_iterator end()const
{
return _pHead;
}
reverse_iterator rbegin()
{
return (--end());
}
reverse_iterator rend()
{
return (--begin());
}
const_reverse_iterator rbegin()const
{
return (--end());
}
const_reverse_iterator rend()const
{
return (--begin());
}
//………………………………
};
}
3. vector 的 Reverse_Iterator
反向迭代器的实现同 list 。
报错:返回临时对象
自定义对象const变量调用非const函数的典型例子:匿名对象(具有常性)调用非const成员函数,当我们只是想用调用某个自定义类的成员函数而不想为此特意创建自定义对象时,我们常常通过匿名对象来调用其成员函数。
对于上图所描述的报错,可以通过将 --end() 改成 end()-1。下面展示一种更优的处理办法。
4. 完善 Reverse_Iterator
思路:
注意:这里处理 --(减减) 操作必须通过一个临时变量来执行,该操作不能直接作用在 reverse_iterator 的成员变量 it 上!不然每次对反向迭代器解引用一次还会附带一次 -- 操作!
完整的迭代器实现:(ps.只展示和反向迭代器直接相关的,其他部分省略。另外,注意只要是自己实现了构造函数,一定要有默认构造,否则可能会出现问题)
namespace Btl
{
// 适配器 -- 复用
template<class Iterator, class Ref, class Ptr>
struct Reverse_iterator
{
typedef Reverse_iterator<Iterator, Ref, Ptr> Self;
Iterator _it;
Reverse_iterator()//默认构造函数
{}
Reverse_iterator(Iterator it)
:_it(it)
{}
Ref operator*()
{
Iterator tmp = _it;
return *(--tmp);
}
Ptr operator->()
{
return &(operator*());
}
Self& operator++()
{
--_it;
return *this;
}
Self& operator--()
{
++_it;
return *this;
}
Self operator++(int)
{
Self tmp = _it;
--_it;
return tmp;
}
Self operator--(int)
{
Self tmp = _it;
++_it;
return tmp;
}
bool operator!=(const Self& s)
{
return _it != s._it;
}
bool operator==(const Self& s)
{
return _it == s._it;
}
};
}
namespace Btl
{
template<class T>
class vector
{
public:
// Vector的迭代器是一个原生指针
typedef T* iterator;
typedef const T* const_iterator;
typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;
typedef Reverse_iterator<const_iterator, T&, T*> const_reverse_iterator;
iterator begin()
{
return _start;
}
iterator end()
{
return _finish;
}
const_iterator cbegin()const
{
return _start;
}
const_iterator cend()const
{
return _finish;
}
reverse_iterator rbegin()
{
return end();
}
reverse_iterator rend()
{
return begin();
}
const_reverse_iterator rbegin()const
{
return cend();
}
const_reverse_iterator rend()const
{
return cbegin();
}
//…………………………………………………………
};
}
namespace Btl
{
//list类
template<class T>
class list
{
public:
typedef ListIterator<T, T&, T*> iterator;
typedef ListIterator<T, const T&, const T&> const_iterator;
typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;
typedef Reverse_iterator<const_iterator, T&, T*> const_reverse_iterator;
///
// List Iterator
iterator begin()
{
return _pHead->_pNext;
}
iterator end()
{
return _pHead;
}
const_iterator begin() const
{
return _pHead->_pNext;
}
const_iterator end()const
{
return _pHead;
}
reverse_iterator rbegin()
{
return end();
}
reverse_iterator rend()
{
return begin();
}
const_reverse_iterator rbegin()const
{
return end();
}
const_reverse_iterator rend()const
{
return begin();
}
//…………………………………………………………………………
};
}
END