【C++ ———list的模拟实现】

本文详细介绍了C++中使用模板创建了一个List类,包含迭代器的定义和常用操作方法如push_back,push_front,erase,insert等,以及list对象的构造、交换和遍历示例。
摘要由CSDN通过智能技术生成

前言

此文只是常见接口的模拟实现,但是还是具有很多不同具体还是要参考官方版本的文档https://legacy.cplusplus.com/reference/list/list/?kw=list


原代码

#pragma once
#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdbool.h>
#include<vector>


using namespace std;


namespace goat
{
	template<class T>
	struct List_node
	{
		T _data;
		List_node<T>* _next;
		List_node<T>* _prev;

		List_node(const T& x = T())
			:_data(x)
			,_next(nullptr)
			,_prev(nullptr)
		{

		}

	};
	//template<T,T&,T*>
	//多出来的两个额外模板参数是为了让后续const迭代器和普通迭代器共用一个模板。
	//typedef __list_iterator<T,T&,T*> iterator;
	//typedef __list_iterator<T, const T&, const T*> const_iterator;
	//可以参考上面代码的传值。
	template<class T ,class Ref, class Ptr>
	struct __list_iterator
	{
		typedef List_node<T> Node;
		typedef __list_iterator<T,Ref,Ptr> self;
		Node* _node;
		__list_iterator(Node* node)
			:_node(node)
		{}

		self& operator++()
		{
			_node = _node->_next;
			return *this;
		}
		self operator++(int)
		{
			Node* tmp(*this);
			_node = _node->_next;
			return tmp;
		}
		self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}
		self& operator--(int)
		{
			Node* tmp(*this);
			_node = _node->_prev;
			return tmp;
		}
		Ref& operator*()
		{
			return (*_node)._data;
		}
		bool operator!=(const self& it)
		{
			return _node != it._node;
		}
		bool operator==(const self& it)
		{
			return _node == it._node;
		}
		Ptr* operator->()
		{
			return &_node->_data;
		}
	};



	//const迭代器不能写成这种格式:const iterator。这种是对iterator本身进行修饰,但是我们的迭代器还要实现++/--的功能
	//所以我们应该对iterator指向的内容进行const修饰。
	//不过这样写因为只有两个函数修改而导致了相当于重新写了一个迭代器显得很冗余
	/*template<class T>
	struct __list_const_iterator
	{
		typedef List_node<T> Node;
		typedef __list_const_iterator self;
		Node* _node;
		__list_const_iterator(Node* node)
			:_node(node)
		{}

		self& operator++()
		{
			_node = _node->_next;
			return *this;
		}
		self operator++(int)
		{
			Node* tmp(*this);
			_node = _node->_next;
			return tmp;
		}
		self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}
		self& operator--(int)
		{
			Node* tmp(*this);
			_node = _node->_prev;
			return tmp;
		}
		
		bool operator!=(const self& it)
		{
			return _node != it._node;
		}
		bool operator==(const self& it)
		{
			return _node == it._node;
		}
		const T* operator->() const
		{
			return &_node->_data;
		}
		const T& operator*() const
		{
			return (*_node)._data;
		}
	};*/

	template<class T>
	class list
	{
		typedef List_node<T> Node;
	public:
		typedef __list_iterator<T,T&,T*> iterator;
		typedef __list_iterator<T,const T&,const T*> const_iterator;

	

		//迭代器
		iterator begin()
		{
			return iterator(_head->_next);
		//  return _head->_next  隐式类型转换(这样也可以)
		}
		iterator end()
		{
			return iterator(_head);
		
		}
		const_iterator begin() const
		{
			return const_iterator(_head->_next);
			//  return _head->_next  隐式类型转换(这样也可以)
		}
		const_iterator end() const
		{
			return const_iterator(_head);

		}
		void empty_init()
		{
			_head = new Node;
			_head->_prev = _head;
			_head->_next = _head;


			size = 0;
		}
		//l1(l2)
		list(const list<T>& lt)
		{
			empty_init();
			for (auto e : lt)
			{
				push_back(e);
			}
		}

		list()
		{
			empty_init();


		}
		~list()
		{
			clear();

			delete _head;
			_head = nullptr;
		}
		void clear()
		{
			iterator it = begin();
			//for (auto e : it)
			//{
			//	e=erase(e);
			//}
			while (it != end())
			{
				it = erase(it);
			}
		}

		void push_back(const T& x)
		{
			//Node* tail = _head->_prev;
			//Node* newnode = new Node(x);
			//newnode->_next = _head;
			//tail->_next = newnode;

			//newnode->_prev = tail;
			//_head->_prev = newnode;
			insert(end(), x);

		}

		void push_front(const T& x)
		{
			insert(begin(), x);
			
		}
		void pop_back()
		{
			erase(--end());
		}
		void pop_front()
		{
			erase(begin());
		}
		iterator insert(iterator pos,const T& x)
		{
			//Node* newnode = new Node(x);
			//Node* cur = pos._node;

			//Node* prev = cur->_prev;

			//prev->_next = newnode;
			//newnode->_prev = prev;

			//cur->_prev = newnode;
			//newnode->_next = cur;
			//return iterator(newnode);

			Node* cur = pos._node;
			Node* newnode = new Node(x);

			Node* prev = cur->_prev;

			// prev newnode cur
			prev->_next = newnode;
			newnode->_prev = prev;

			cur->_prev = newnode;
			newnode->_next = cur;
			

			++size;
			return iterator(newnode);


		}


		iterator erase(iterator pos)
		{
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* next = cur->_next;
			delete cur;
			(*prev)._next = next;
			(*next)._prev = prev;
			
			--size;
			return iterator(next);
		}


		void swap(list<T>& lt)
		{
			std::swap(_head, lt._head);
			std::swap(size, lt.size);

		}
		list<T>& operator=(list<T> lt)
		{
			//	if (this != &lt)
			//	{
			//		clear();
			//		for (auto e : lt)
			//		{
			//			push_back(e);
			//		}
			//	}
			//return *this;

				swap(lt);
				return *this;
		}
		size_t Size()
		{
			return size;
		}

		bool empty()
		{
			return size == 0;

		}

	private:
		Node* _head;
		size_t size;

	};
	//print的方式:

	//只支持int类型
	void Printf_list(const list<int>& lt)
	{
		list<int>::const_iterator lt1 = lt.begin();
		while (lt1 != lt.end())
		{
			//*lt1 = 10;
			cout << *lt1 << " ";
			++lt1;
		}
		cout << endl;
		for (auto e : lt)
		{	
			
			cout << e+10 << " ";
		}
		cout << endl;
	}


	//支持list类型
	//template<class T>
	template<typename T>
	void Printf_list(const list<T>& lt)
	{
		//list<int>::const_iterator lt1 = lt.begin();
		//为什么int能直接用,因为它已经实例化了


		//typename是什么意思呢?
		//当list<T>是为实例化的类模板,编译器不能去里面找
		//编译器就无法确定const_iterator是我们的内嵌类型还是静态成员变量
		//前面加typename就是告诉编译器,这是一个类型,等list<T>实例化了
		//再去类里面去取。
		typename list<T>::const_iterator lt1 = lt.begin();
		//类还没有实例化,编译器不敢去取还没有实例化的类中的成员函数,
		//这里class就要替换成typename,且这段代码前要加上typename。
		//typename
		while (lt1 != lt.end())
		{
			//*lt1 = 10;
			cout << *lt1 << " ";
			++lt1;
		}
		cout << endl;
		//for (auto e : lt)
		//{

		//	cout << e + 10 << " ";
		//}
		//cout << endl;
	}

	//支持很多容器类型(要注意有些容器没有重载流插入要额外实现)
	template<typename container>
	void Printf_container(const container& con)
	{	
		typename container::const_iterator it = con.begin();
		while (it != con.end())
		{
			//*lt1 = 10;
			cout << *it << " ";//数据类型要重载流插入,如果没有重载流插入就使用仿函数
			++it;
		}
		cout << endl;
		//泛型编程的本质就是,本来我们的干的活交给了编译器。

	}


  //以下都是例子和测试
	void test_list1()
	{
		list<int> l1;
		l1.push_back(1);
		l1.push_back(2);
		l1.push_back(3);
		l1.push_back(4);
		l1.push_back(5);

		l1.erase(l1.begin());

		list<int>::iterator it = l1.begin();
		while (it != l1.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;


		list<int> l2;
		l2.push_back(1);
		l2.push_back(2);
		l2.push_back(3);
		l2.push_back(9);
		l2.push_back(8);

		list<int> l3(l2);

		for (auto e : l3)
		{
			cout << e << " ";
		}
		cout << endl;

		l1 = l2;
		for (auto e : l3)
		{
			cout << e << " ";
		}
		cout << endl;





	}
	struct AA
	{
		AA(int a1 = 0, int a2 = 0)
			:_a1(a1)
			, _a2(a2)
		{}

		int _a1;
		int _a2;
	};

	void test_list2()
	{
		list<AA> lt1;
		lt1.push_back(AA(1, 1));
		lt1.push_back(AA(2, 2));
		lt1.push_back(AA(3, 3));
		list<AA>::iterator it = lt1.begin();
		while (it != lt1.end())
		{
			cout << (*it)._a1 << " " << (*it)._a2 << " ";
			//cout << it->_a1 << " " << it->_a2 << " ";
			++it;
		}
		cout << endl;
	}

	
	void test_list3()
	{
		list<int> l1;
		l1.push_back(1);
		l1.push_back(2);
		l1.push_back(3);
		l1.push_back(4);
		l1.push_back(5);
		
		//Printf_list(l1);
		Printf_container(l1);
		list<string> l2;
		l2.push_back("1111111111");
		l2.push_back("1111111111");
		l2.push_back("1111111111");
		l2.push_back("1111111111");
		l2.push_back("1111111111");
		//Printf_list(l2);
		Printf_container(l2);
		vector<string> v;
		v.push_back("222222222");
		v.push_back("222222222");
		v.push_back("222222222");
		v.push_back("222222222");
		v.push_back("222222222");
		Printf_container(v);

	}
	
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值