在上篇文章中,实现了的大部分功能以及部分迭代器。本片文章将对剩下的功能进行补充。
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;
}