C++(17.5)——list模拟实现扩展

在上篇文章中,实现了的大部分功能以及部分迭代器。本片文章将对剩下的功能进行补充。

1. const迭代器:

对于上篇文章中实现的迭代器只能使用于非类型的对象。对于类型的遍历,则需要额外编写类型的迭代器。例如对于下面的场景:

cpp 复制代码
void print_list(const list<int>& s)
	{
		list<int>::const_iterator it2 = s.begin();
		while (it2 != s.end())
		{
			cout << *it2;
			it2++;
		}
	}

对于与非类型的变量的区别,是类型的对象不能修改。因此,实现迭代器的第一种方法,便是将非迭代器的相关代码进行复制然后进行改动,基于类型本身的性质,只需要将函数的返回值类型改为类型即可,对应代码如下:

cpp 复制代码
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;
	};

在完成上述步骤后,还需要在中,引入__,并且为了方便书写,利用函数将其改写为_。将成员函数进行复制,然后改为成员函数,代码如下:

cpp 复制代码
const_iterator begin() const
		{
			return _phead->_next;
		}

		const_iterator end() const
		{
			return _phead;
		}

此时,再运行上方给出的代码:

cpp 复制代码
void print_list(const list<int>& s)
	{
		list<int>::const_iterator it2 = s.begin();
		while (it2 != s.end())
		{
			cout << *it2;
			it2++;
		}
	}
cpp 复制代码
print_list(It);

运行结果如下:

上述步骤虽然可以实现迭代器的使用,但是两种迭代器的代码重复率过高。只有二者的成员函数的返回值类型不同,以及迭代器名称不同。为了简化上述代码,可以使用两个模板参数,即:

cpp 复制代码
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;
	};

其中,第二个模板参数用于表示返回类型是还是非。并且,对中引入的迭代器类型,通过传递不同的参数来进行区分,即:

cpp 复制代码
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. 代码总览:

cpp 复制代码
#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++;
		}
	}
}
cpp 复制代码
#include"list_1.h"

int main()
{
	violent::test3();
	return 0;
}
相关推荐
TDengine (老段)21 小时前
TDengine C/C++ 连接器进阶指南
大数据·c语言·c++·人工智能·物联网·时序数据库·tdengine
a35354138221 小时前
设计模式-代理模式
c++·设计模式·代理模式
TTGGGFF1 天前
Supertonic 部署与使用全流程保姆级指南(附已部署镜像)
开发语言·python
木木木一1 天前
Rust学习记录--C7 Package, Crate, Module
开发语言·学习·rust
love530love1 天前
升级到 ComfyUI Desktop v0.7.0 版本后启动日志报 KeyError: ‘tensorrt‘ 错误解决方案
开发语言·windows·python·pycharm·virtualenv·comfyui·comfyui desktop
Evand J1 天前
【MATLAB例程】【空地协同】UAV辅助的UGV协同定位,无人机辅助地面无人车定位,带滤波,附MATLAB代码下载链接
开发语言·matlab·无人机·无人车·uav·协同定位·ugv
chao1898441 天前
基于MATLAB实现多变量高斯过程回归(GPR)
开发语言·matlab·回归
ytttr8731 天前
隐马尔可夫模型(HMM)MATLAB实现范例
开发语言·算法·matlab
天远Date Lab1 天前
Python实战:对接天远数据手机号码归属地API,实现精准用户分群与本地化运营
大数据·开发语言·python
listhi5201 天前
基于Gabor纹理特征与K-means聚类的图像分割(Matlab实现)
开发语言·matlab