void f()
{
Node* pnode = _head->_next;
iterator it = _head->_next;
*pnode;
*it;
++pnode;
++it;
}
Node*原生指针和一个迭代器对象,他们占用空间是一样大的,都是4byte并且存的值也是一样的。但是对他们使用运算符的意义和结果是不一样的。
迭代器是借助节点的指针访问修改链表
节点属于链表,不属于迭代器,所以他不管释放
都不需要自己实现,默认生成的即可
原因分析:
你将一个迭代器去拷贝构造成另外一个迭代器,是需要浅拷贝还是深拷贝?
浅拷贝,所以就不需要。
const对于我们的要求来说,只需要满足只读不写就可以了
他的一些常规操作和我们实现的普通类型是一样的
我们参考list的源代码,我们可以使用模板参数来进行实现
代码请见下面list实现
struct Date
{
int _year;
int _month;
int _day;
Date(int year = 1, int month = 1, int day = 1)
:_year(year)
, _month(month)
, _day(day)
{}
};
void test_list2()
{
list<Date> lt;
lt.push_back(Date(2022, 3, 12));
lt.push_back(Date(2022, 3, 13));
lt.push_back(Date(2022, 3, 14));
list<Date>::iterator it = lt.begin();
while (it != lt.end())
{
//这样是可以直接使用的,我们不模拟实现->就可以直接使用
//cout << (*it)._year << "/" << (*it)._month << "/" << (*it)._day << endl;
//但是如何实现?-> 是我们的迭代器更像指针
cout << it->_year << "/" << it->_month << "/" << it->_day << endl;
++it;
}
cout << endl;
}
先说结果,但是为什这样可以?
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &_node->_data;
}
it->_year相当于 it.operator->()
返回的是Date*
Date* 访问_year 应该是it->->_year
但是这样写的话,运算符可读性太差
所以这里编译器进行了优化,省略了一个->
素有类型只要想重载->都是这样的,都会优化。省略一个->
// 这里insert以后,pos是否失效?不失效
iterator 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;
return iterator(newnode);
}
// 这里erase以后,pos是否失效?一定失效
// 节点删除了,迭代器也就失效了
iterator erase(iterator pos)
{
assert(pos != end());
Node* prev = pos._node->_prev;
Node* next = pos._node->_next;
delete pos._node;
prev->_next = next;
next->_prev = prev;
return iterator(next);
}
延伸:
vector的erase之后迭代器会不会失效?
vector她erase后,说不定空间会缩容,所以可能会失效
list(size_t n, const T& val = T())
{
_head = new Node();
_head->_next = _head;
_head->_prev = _head;
for (size_t i = 0; i < n; ++i)
{
push_back(val);
}
}
当我们构造:
// list lt2(5, 1); 时?就会出现问题,因为:
template<class InputIterator>
list(InputIterator first, InputIterator last)
{
_head = new Node();
_head->_next = _head;
_head->_prev = _head;
while (first != last)
{
push_back(*first);
++first;
}
}
1 是int类型,int不能解引用
reverse_iterator.h
#pragma once
namespace sakeww
{
//
// Iterator是哪个容器的迭代器,reverse_iterator就可以
// 适配出哪个容器的反向迭代器,复用的体现
template <class Iterator, class Ref, class Ptr>
class reverse_iterator
{
typedef reverse_iterator<Iterator, Ref, Ptr> self;
//typedef typename Iterator::Ref Ref;
//typedef typename Iterator::Ptr Ptr;
//凡是要取一个模板的内嵌类型,就要加typename,
//告诉编译器后面的是类型,先让他过,现在去找他的类型是找不到的
//等着类模板实例化了再去找他的具体类型
public:
reverse_iterator(Iterator it)
:_it(it)
{}
typename Iterator::reference operator*()
{
//我们理解的实现
//return *_it;
//源码实现
Iterator prev = _it;
return *--prev;
}
typename Iterator::pointer operator->()
{
return &operator*();
}
self& operator++()
{
--_it;
return *this;
}
self& operator--()
{
++_it;
return *this;
}
bool operator!= (const self& rit) const
{
return _it != rit._it;
}
private:
Iterator _it;
};
}
list.h(内含部分测试用例)
#include"reverse_iterator.h"
namespace sakeww
{
template<class T>
struct ListNode
{
ListNode* _next;
ListNode* _prev;
T _data;
ListNode(const T& data = T())
:_next(nullptr)
, _prev(nullptr)
, _data(data)
{}
};
template<class T, class Ref, class Ptr>
struct __list_iterator
{
typedef ListNode<T> Node;
typedef __list_iterator<T, Ref, Ptr> self;
typedef Ref reference;
typedef Ptr pointer;
//typedef __list_iterator
Node* _node;
__list_iterator(Node* x)
:_node(x)
{}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &_node->_data;
}
// ++it
self& operator++()
{
_node = _node->_next;
return *this;
}
// it++
self operator++(int)
{
self tmp(*this);
_node = _node->_next;
return tmp;
}
// --it
self& operator--()
{
_node = _node->_prev;
return *this;
}
// it--
self operator--(int)
{
self tmp(*this);
_node = _node->_prev;
return tmp;
}
bool operator!=(const self& it) const
{
return _node != it._node;
}
bool operator==(const self& it) const
{
return _node != it._node;
}
};
template<class T>
class list
{
typedef ListNode<T> Node;
public:
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;
typedef reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;
typedef reverse_iterator<iterator, T&, T*> reverse_iterator;
reverse_iterator rbegin()
{
return reverse_iterator(end());
}
reverse_iterator rend()
{
return reverse_iterator(begin());
}
iterator begin()
{
return iterator(_head->_next);
}
iterator end()
{
return iterator(_head);
}
const_iterator begin() const
{
return const_iterator(_head->_next);
}
const_iterator end() const
{
return const_iterator(_head);
}
list()
{
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
}
// list lt1(5, Date(2022, 3, 15));
// list lt2(5, 1);
list(int n, const T& val = T())
{
_head = new Node();
_head->_next = _head;
_head->_prev = _head;
for (int i = 0; i < n; ++i)
{
push_back(val);
}
}
list(size_t n, const T& val = T())
{
_head = new Node();
_head->_next = _head;
_head->_prev = _head;
for (size_t i = 0; i < n; ++i)
{
push_back(val);
}
}
template<class InputIterator>
list(InputIterator first, InputIterator last)
{
_head = new Node();
_head->_next = _head;
_head->_prev = _head;
while (first != last)
{
push_back(*first);
++first;
}
}
// lt2(lt1)
list(const list<T>& lt)
{
_head = new Node();
_head->_next = _head;
_head->_prev = _head;
list<T> tmp(lt.begin(), lt.end());
std::swap(_head, tmp._head);
}
// lt2 = lt1
list<T>& operator=(list<T> lt)
{
std::swap(_head, lt._head);
return *this;
}
//lt2(lt1)传统写法
// list(const list& lt)
//{
// _head = new Node();
// _head->_next = _head;
// _head->_prev = _head;
// for (auto e : lt)
// {
// push_back(e);
// }
//}
lt2 = lt1传统写法
//list& operator=(const list& lt)
//{
// if (this != <)
// {
// clear();
// for (auto e : lt)
// {
// push_back(e);
// }
// }
// return *this;
//}
~list()
{
clear();
delete _head;
_head = nullptr;
}
void clear()
{
/*iterator it = begin();
while (it != end())
{
iterator del = it++;
delete del._node;
}
_head->_next = _head;
_head->_prev = _head;*/
iterator it = begin();
while (it != end())
{
erase(it++);
}
}
//头插
void push_front(const T& x)
{
insert(begin(), x);
}
void push_back(const T& x)
{
//Node* tail = _head->_prev;
//Node* newnode = new Node(x);
//tail->_next = newnode;
//newnode->_prev = tail;
//newnode->_next = _head;
//_head->_prev = newnode;
insert(end(), x);
}
//尾删
void pop_back()
{
erase(--end());
}
//头删
void pop_front()
{
erase(begin());
}
// 这里insert以后,pos是否失效?不失效
iterator 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;
return iterator(newnode);
}
// 这里erase以后,pos是否失效?一定失效
iterator erase(iterator pos)
{
assert(pos != end());
Node* prev = pos._node->_prev;
Node* next = pos._node->_next;
delete pos._node;
prev->_next = next;
next->_prev = prev;
return iterator(next);
}
private:
Node* _head;
};
void print_list(const list<int>& lt)
{
list<int>::const_iterator it = lt.begin();
while (it != lt.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}
void test1()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
//lt.f();
// 访问修改容器
list<int>::iterator it = lt.begin();
while (it != lt.end())
{
*it *= 2; // 修改
cout << *it << " ";
++it;
}
cout << endl;
print_list(lt);
}
struct Date
{
int _year;
int _month;
int _day;
Date(int year = 1, int month = 1, int day = 1)
:_year(year)
, _month(month)
, _day(day)
{}
};
void test2()
{
list<Date> lt;
lt.push_back(Date(2022, 3, 12));
lt.push_back(Date(2022, 3, 13));
lt.push_back(Date(2022, 3, 14));
list<Date>::iterator it = lt.begin();
while (it != lt.end())
{
//cout << (*it)._year << "/" << (*it)._month << "/" << (*it)._day << endl;
cout << it->_year << "/" << it->_month << "/" << it->_day << endl;
++it;
}
cout << endl;
}
void test3()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
list<int> lt2(lt);
for (auto e : lt2)
{
cout << e << " ";
}
cout << endl;
list<int> lt3;
lt3.push_back(10);
lt3.push_back(10);
lt3.push_back(10);
lt3.push_back(10);
lt = lt3;
for (auto e : lt)
{
cout << e << " ";
}
cout << endl;
}
void test4()
{
list<Date> lt(5, Date(2022, 3, 15));
for (auto e : lt)
{
cout << e._year << "/" << e._month << "/" << e._day << endl;
}
cout << endl;
list<int> lt2(5, 1);
for (auto e : lt2)
{
cout << e << " ";
}
cout << endl;
}
void test5()
{
list<int> lt1;
lt1.push_back(1);
lt1.push_back(2);
lt1.push_back(3);
lt1.push_back(4);
list<int>::iterator it = lt1.begin();
while (it != lt1.end())
{
//*it *= 2; // 修改
cout << *it << " ";
++it;
}
cout << endl;
list<int>::reverse_iterator rit = lt1.rbegin();
while (rit != lt1.rend())
{
cout << *rit << " ";
++rit;
}
cout << endl;
}
}