在上篇文章中,实现了的大部分功能以及部分迭代器。本片文章将对剩下的功能进行补充。
1. const迭代器:
对于上篇文章中实现的迭代器只能使用于非类型的对象。对于类型的遍历,则需要额外编写类型的迭代器。例如对于下面的场景:
void print_list(const list<int>& s){list<int>::const_iterator it2 = s.begin();while (it2 != s.end()){cout << *it2;it2++;}}
对于与非类型的变量的区别,是类型的对象不能修改。因此,实现迭代器的第一种方法,便是将非迭代器的相关代码进行复制然后进行改动,基于类型本身的性质,只需要将函数的返回值类型改为类型即可,对应代码如下:
template<class T>struct __list_const_iterator{typedef ListNode<T> Node;typedef __list_const_iterator<T> self;__list_const_iterator(Node* node): _node(node){}self& operator++(){_node = _node->_next;return *this;}self& operator++(int){self tmp(_node);_node = _node->_next;return tmp;}const T& operator*(){return _node->_data;}bool operator!=(const self& s){return _node != s._node;}bool operator==(const self& s){return _node == s._node;}Node* _node;};
在完成上述步骤后,还需要在中,引入____,并且为了方便书写,利用函数将其改写为_。将成员函数进行复制,然后改为成员函数,代码如下:
const_iterator begin() const{return _phead->_next;}const_iterator end() const{return _phead;}
此时,再运行上方给出的代码:
void print_list(const list<int>& s){list<int>::const_iterator it2 = s.begin();while (it2 != s.end()){cout << *it2;it2++;}}
print_list(It);
运行结果如下:
上述步骤虽然可以实现迭代器的使用,但是两种迭代器的代码重复率过高。只有二者的成员函数的返回值类型不同,以及迭代器名称不同。为了简化上述代码,可以使用两个模板参数,即:
template<class T,class Ref>struct __list_iterator{typedef ListNode<T> Node;typedef __list_iterator<T,Ref> self;__list_iterator(Node* node): _node(node){}self& operator++(){_node = _node->_next;return *this;}self& operator++(int){self tmp(_node);_node = _node->next;return tmp;}Ref& operator*(){return _node->_data;}bool operator!=(const self& s){return _node != s._node;}Node* _node;};
其中,第二个模板参数用于表示返回类型是还是非。并且,对中引入的迭代器类型,通过传递不同的参数来进行区分,即:
template<class T>class list{typedef ListNode<T> Node;public:typedef __list_iterator<T,T&> iterator;typedef __list_iterator<T,const T&> const_iterator;iterator begin(){return _phead->_next;}iterator end(){return _phead;}const_iterator begin() const{return _phead->_next;}const_iterator end() const{return _phead;}Node* _phead;};
2. 代码总览:
#include<assert.h>
#include<iostream>
using namespace std;namespace violent
{template<class T>struct ListNode{ListNode(const T& x = T()): _prev(nullptr), _next(nullptr), _data(x){}ListNode<T>* _prev;ListNode<T>* _next;T _data;};template<class T,class Ref>struct __list_iterator{typedef ListNode<T> Node;typedef __list_iterator<T,Ref> self;__list_iterator(Node* node): _node(node){}self& operator++(){_node = _node->_next;return *this;}self& operator++(int){self tmp(_node);_node = _node->_next;return tmp;}Ref& operator*(){return _node->_data;}bool operator!=(const self& s){return _node != s._node;}T* operator->(){return &_node->_data;}Node* _node;};/*template<class T>struct __list_const_iterator{typedef ListNode<T> Node;typedef __list_const_iterator<T> self;__list_const_iterator(Node* node): _node(node){}self& operator++(){_node = _node->_next;return *this;}self& operator++(int){self tmp(_node);_node = _node->_next;return tmp;}const T& operator*(){return _node->_data;}bool operator!=(const self& s){return _node != s._node;}bool operator==(const self& s){return _node == s._node;}Node* _node;};*/template<class T>class list{typedef ListNode<T> Node;public:typedef __list_iterator<T,T&> iterator;typedef __list_iterator<T,const T&> const_iterator;list(){_phead = new Node;_phead->_next = _phead;_phead->_prev = _phead;}void empty(){_phead = new Node;_phead->_next = _phead;_phead->_prev = _phead;}list(const list<T>& s){empty();for (auto e : s){push_back(e);}}void swap(list<T>& s){std::swap(_phead, s._phead);}list<T>& operator=(list<T> s){swap(s);return *this;}iterator begin(){return _phead->_next;}iterator end(){return _phead;}const_iterator begin() const{return _phead->_next;}const_iterator end() const{return _phead;}/*void push_back(const T& x){Node* newnode = new Node(x);Node* tail = _phead->_prev;tail->_next = newnode;newnode->_prev = tail;newnode->_next = _phead;_phead->_prev = newnode;}*/void push_back(const T& x){insert(_phead, x);}void push_front(const T& x){insert(_phead->_next, x);}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;}void pop_back(){erase(_phead->_prev);}void pop_front(){erase(_phead->_next);}iterator erase(iterator pos){assert(pos != end());Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;return next;}void clear(){iterator i2 = begin();while (i2 != end()){i2 = erase(i2);}}~list(){clear();delete _phead;_phead = nullptr;}Node* _phead;};void print_list(const list<int>& s){list<int>::const_iterator it2 = s.begin();while (it2 != s.end()){cout << *it2;it2++;}}void test1(){list<int> It;It.push_back(1);It.push_back(2);It.push_back(3);It.push_back(4);list<int>::iterator it1 = It.begin();while (it1 != It.end()){cout << *it1 << ' ';++it1;}cout << endl;It.insert(It.begin(), 5);It.insert(It.begin(), 6);It.insert(It.begin(), 7);It.insert(It.begin(), 8);It.push_front(9);It.push_front(9);It.push_front(9);for (auto e : It){cout << e << ' ';}cout << endl;It.pop_back();It.pop_back();It.pop_front();It.pop_front();for (auto e : It){cout << e << ' ';}cout << endl;cout << "const迭代器:";print_list(It);}struct AA{AA(int aa1 = 1, int aa2 = 2): _aa1(aa1), _aa2(aa2){}int _aa1;int _aa2;};void test3(){AA a(2, 3);list<AA> It;It.push_back(a);It.push_back(AA());It.push_back(AA(1, 2));list<AA>::iterator it = It.begin();while (it != It.end()){cout << it->_aa1 << endl;it++;}}
}
#include"list_1.h"int main()
{violent::test3();return 0;
}