template<class T>
struct list_node
{
T _data;
list_node<T>* _prev;
list_node<T>* _next;
list_node(const T& val = T())
:_prev(nullptr),
_next(nullptr),
_data(val)
{}
};
template<class T>
struct __list_iterator
{
typedef list_node<T> node;
typedef __list_iterator<T> iterator;
node* _node;
__list_iterator(node* n)
:_node(n)
{}
T& operator*()
{
return _node->_data;
}
iterator& operator++()
{
_node = _node->_next;
return *this;
}
iterator operator++(int)
{
iterator tmp(*this);
_node = _node->_next;
return tmp;
}
iterator& operator--()
{
_node = _node->_prev;
return *this;
}
iterator operator--(int)
{
iterator tmp(*this);
_node = _node->_prev;
return tmp;
}
bool operator!=(const iterator& it )const
{
return _node != it._node;
}
bool operator==(const iterator& it)const
{
return _node == it._node;
}
};
看下面这段代码能否编译通过
如果传一个const对象,那么就需要实现对应的const迭代器,否则会出现权限的放大,是会报错的。
如果声明成这样呢?
typedef const iterator const_iterator
这是错误的。这就相当于iterator本身是const,那么就不能执行++操作,迭代器不能动还叫啥迭代器。所以我们处理的方法是返回一个const迭代器,重新实现一个const_iterator类。基本都复用普通迭代器的代码,就解引用时返回const T&。
template<class T>
struct __list_const_iterator
{
typedef list_node<T> node;
typedef __list_const_iterator<T> const_iterator;
node* _node;
__list_const_iterator(node* n)
:_node(n)
{}
const T& operator*()
{
return _node->_data;
}
const_iterator& operator++()
{
_node = _node->_next;
return *this;
}
const_iterator operator++(int)
{
const_iterator tmp(*this);
_node = _node->_next;
return tmp;
}
const_iterator& operator--()
{
_node = _node->_prev;
return *this;
}
const_iterator operator--(int)
{
const_iterator tmp(*this);
_node = _node->_prev;
return tmp;
}
bool operator!=(const const_iterator& it)const
{
return _node != it._node;
}
bool operator==(const const_iterator& it)const
{
return _node == it._node;
}
};
这样我们代码就不报错,顺利打印出了数据
const iterator begin()const//后面的const修饰的是this指针指向的内容(*this),即_head本身不能被改变,指向对象的内容可变
{
return const iterator(_head->_next);
}
const迭代器还要去实现一个几乎相同的类,就改了个名字叫const_iterator,除了解引用返回T的引用时不同(const T&),那么我们在实现iterator迭代器类的时候加一个模版参数Ref表示引用,typedef不同的迭代器实例化不同的Ref即可解决。
不得不说想出这种写法的人真的是个天才
前面说过,此处大家可将迭代器暂时理解成类似于指针,迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的**,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响**
注意反向迭代器的实现是复用了正向迭代器
#include
#include
namespace pqd
{
template<class T>
struct list_node
{
T _data;
list_node<T>* _prev;
list_node<T>* _next;
list_node(const T& val = T())
:_prev(nullptr),
_next(nullptr),
_data(val)
{}
};
template<class T,class Ref,class Ptr>
struct __list_iterator
{
typedef list_node<T> node;
typedef __list_iterator<T,Ref,Ptr> iterator;
node* _node;
__list_iterator(node* n)
:_node(n)
{}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &_node->_data;
}
iterator& operator++()
{
_node = _node->_next;
return *this;
}
iterator operator++(int)
{
iterator tmp(*this);
_node = _node->_next;
return tmp;
}
iterator& operator--()
{
_node = _node->_prev;
return *this;
}
iterator operator--(int)
{
iterator tmp(*this);
_node = _node->_prev;
return tmp;
}
bool operator!=(const iterator& it )const
{
return _node != it._node;
}
bool operator==(const iterator& it)const
{
return _node == it._node;
}
};
template<class Iterator,class Ref,class Ptr>
struct ReverseIterator
{
typedef ReverseIterator<Iterator,Ref,Ptr> Self;
Iterator _cur;
ReverseIterator(Iterator it)
:_cur(it){}
Self& operator++()
{
--_cur;
return *this;
}
Self& operator++(int)
{
Iterator tmp(_cur);
--_cur;
return tmp;
}
Self& operator--()
{
++_cur;
return *this;
}
Self& operator--(int)
{
Iterator tmp(_cur);
++_cur;
return tmp;
}
Ref operator*()
{
Iterator tmp = _cur;
--tmp;
return *tmp;
}
bool operator!=(const Self& s)
{
return _cur != s._cur;
}
};
template<class T>
class list
{
public:
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;
typedef list_node<T> node;
void empty_init()
{
_head = new node;
_head->_prev = _head;
_head->_next = _head;
}
list()
{
empty_init();
}
template<class Iterator>
list(Iterator first, Iterator last)
{
empty_init();
while (first != last)
{
push_back(*first);
++first;
}
}
//lt2(lt1)
/*list(const list& lt)
{
empty_init();
for (auto e : lt)
{
push_back(e);
}
}*/
//现代写法
void swap(list<T>& lt)
{
std::swap(_head, lt._head);
}
list(const list<T>& lt)
{
empty_init();
list<T> tmp(lt.begin(), lt.end());
swap(tmp);
}
list<T>& operator=(list<T> lt)
{
swap(lt);
return *this;
}
iterator begin()
{
return iterator(_head->_next);
}
const_iterator begin()const//后面的const修饰的是this指针指向的内容(*this),即_head本身不能被改变,指向对象的内容可变
{
return const_iterator(_head->_next);
}
iterator end()
{
return iterator(_head);
}
const_iterator end()const
{
return const_iterator(_head);
}
reverse_iterator rbegin()
{
return reverse_iterator(end());
}
reverse_iterator rend()
{
return reverse_iterator(begin());
}
void push_back(const T& val)
{
node* tail = _head->_prev;
node* newnode = new node(val);
tail->_next = newnode;
newnode->_prev = tail;
newnode->_next = _head;
_head->_prev = newnode;
}
void insert(iterator pos, const T& x)
{
node* cur = pos._node;
node* prev = cur->_prev;
node* newnode = new node(x);
prev->_next = newnode;
newnode->_prev = prev;
newnode->_next = cur;
cur->_prev = newnode;
}
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);
}
void pop_back()
{
erase(--end());
}
void clear()//不清理头节点
{
iterator it = begin();
while (it != end())
{
it=erase(it);//或者erase(it++);返回的是it++前的拷贝
it++;
}
}
~list()
{
clear();
delete _head;
_head = nullptr;
}
private:
node* _head;
};
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, 2));
lt.push_back(AA(1, 3));
lt.push_back(AA(1, 4));
list<AA>::iterator it = lt.begin();
while (it != lt.end())
{
std::cout << it->_a1 << ":" << it->_a2 << std::endl;
it++;
}
lt.clear();
}
void print_list(const list<int>& lt)
{
list<int>::const_iterator it = lt.begin();
while (it != lt.end())
{
std:: cout << *it << " ";
++it;
}
}
void test_list1()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
print_list(lt);
}
void test_list3()
{
list<int> lt1;
lt1.push_back(1);
lt1.push_back(2);
lt1.push_back(3);
list<int> lt2(lt1);
for (auto e : lt2)
{
std::cout << e << std::endl;
}
}
void test_list4()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(5);
auto rit =lt.rbegin();
while (rit != lt.rend())
{
std::cout << *rit << " ";
++rit;
}
}
}