List迭代器的理解
1.什么是list迭代器?
list迭代器其实就是一个迭代器指针,只不过这个迭代器是经过封装的对象,使得它可以满足list容器中节点的迭代器功能
2.为什么要有list迭代器?
list是一个双向带头的链表结构,普通的指针不能够让他随意的进行++ – *等操作,因此这些功能只能够自己封装成一个迭代器对象进行使用。
3.如何构建list迭代器
- 1.构建list节点
template <class T>
struct ListNode
{
ListNode(const T& _data=T())
:prev(nullptr),
next(nullptr),
data(_data)
{}
ListNode<T>* prev;
ListNode<T>* next;
T data;
};
- 2.构建初代迭代器
template<class T>
class list_iterator
{
typedef list_iterator<T>* pNode;
typedef list_iterator<T> self;
public:
list_iterator(pNode _pointer)
:pointer(_pointer)
{}
list_iterator(const self& l)
pointer(l.pointer)
{}
T& operator*()
{
return pointer->data;
}
T* operator->()
{
return &(pointer->data);
}
self& operator++()
{
pointer = pointer->next;
return pointer;
}
self operator++(int)
{
self tmp(*this);
pointer = pointer->next;
return tmp;
}
self& operator--()
{
pointer = pointer->prev;
return pointer;
}
self operator--(int)
{
self tmp(*this);
pointer = pointer->prev;
return tmp;
}
bool operator==(self& l)
{
return pointer == l.pointer;
}
bool operator!=(self& l)
{
return pointer == l.pointer;
}
private:
pNode pointer;
};
4.list自带指针与构造迭代器的区别
//自带指针
ListNode* l1;
//构造的迭代器
list_iterator<T> l1;
- 两者之间都是指针,因此都是占据4个字节
- 不同的是,l1就是单纯的指针,不够通过*找到data值,同时不能够++或者–的操作。但是与l1不同,l2在l1的指针基础之上有进行了一系列运算符的重载,使得它有了许多新的功能,让他具备了迭代器的功能
5.更新版的迭代器
为了让list迭代器更加的灵活使用,可以将上面的迭代器做一个扩充版
typedef list_iterator<T,Ref,Ptr>* pNode;
typedef list_iterator<T,Ref,Ptr> self;
这样当我们需要做一个const的迭代器时,就可以不用写多份代码,使得代码冗余.
当我们需要普通版本的迭代器时就可以传入
typedef list_iterator<T,T&,T*> self;
当我们需要const版本的时候就可以传入
typedef list_iterator<T,const T&,const T*> self;
6.特殊迭代器函数的介绍
T*operator->()
{
return &(pointer->data);
}
- 上面的->这里需要注意,为了保证可读性,编译器在此处进行了优化,后面所有的类型在进行重载->时,都会进行省略。