C++从零开始(day32)——list模拟实现2

本文分享了一个大一学生如何在C++中实现list的模拟,包括iterator的访问重载、自定义类型(如Date结构体)的使用,以及const迭代器的作用和模板改造。作者通过实例展示了如何通过迭代器操作list中的数据,以及const迭代器在实际应用中的必要性。
摘要由CSDN通过智能技术生成

这是关于一个普通双非本科大一学生的C++的学习记录贴

在此前,我学了一点点C语言还有简单的数据结构,如果有小伙伴想和我一起学习的,可以私信我交流分享学习资料

那么开启正题

今天分享的是关于list的模拟实现,今天只实现一部分基础函数,重点是const迭代器

1.iterator的访问

由于访问方式的不同,iterator的类实现*的重载同时还应该实现->的重载

T& operator*()
{
	return _node->_data;
}

T* operator->()
{
	return &_node->_data;
}

 2.自定义类型相关

当list中存储的是自定义类型时,我们来看下面的代码

struct Date
{
	int _year;
	int _month;
	int _day;

	Date(int year = 0,int month = 1,int day = 1)
		:_year(year)
		,_month(month)
		,_day(day)
	{}
};

void Test_list2()
{
	list<Date> l;
	l.push_back(Date(2006,9,12));
	l.push_back(Date(1999,5,6));

	list<Date>::iterator it = l.begin();
	while(it != l.end())
	{
		cout << it->_year << "-" << it->_month << "-" << it->_day << endl;
		++it;
	}
} 

很明显如果要通过it访问_year(或_month,_day)应该是it->->_year

第一次->通过it访问到Date,第二次->通过Date再访问到_year

而我们要写出上面说的代码,是不能编译通过的(vs环境下),而写一次->可以编译通过,这是因为为了增强代码的可读性,编译器在这里特殊处理了,不需要我们写两次,一次即可

3.const迭代器

实际运用中我们难免遇到const迭代器的存在

const迭代器是const对象的迭代器,实际运用中,我们不会自己创建const对象,因为没有实际意义,而在一些函数调用中难免出现const修饰的情况,这个时候const迭代器的存在就不可或缺了

对于const与非const的存在,我们需要对模板进行一些改造

typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;

 对应的有下面这些迭代器相关函数

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);
}

下面是完整的代码,以及测试代码

#include<iostream>
#include<list>

using namespace std;

namespace wkl
{
	template<class T>
	struct __list_node
	{
		__list_node* _next;
		__list_node* _prev;
		T _data;

		__list_node(const T& x = T())
			:_next(nullptr)
			,_prev(nullptr)
			,_data(x)
		{}
	};
	// T  T&  T*
	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 = nullptr)
			:_node(node)
		{}

		Ref operator*()
		{
			return _node->_data;
		}

		Ptr operator->()
		{
			return &_node->_data;
		}

		Self& operator++()
		{
			_node = _node->_next;

			return *this;
		}

		Self operator++(int)
		{
			Self tmp(*this);
			_node = _node->_next;

			return tmp;
		}

		Self& operator--()
		{
			_node = _node->_prev;

			return *this;
		}

		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 __list_node<T> Node;
		public:
			typedef __list_iterator<T, T&, T*> iterator;
			typedef __list_iterator<T, const T&, const T*> const_iterator;

			list()
			{
				_head = new Node;
				_head->_next = nullptr;
				_head->_prev = nullptr;
			}

			~list()
			{
				clear();
				delete[] _head;
				_head = nullptr;
			}

			void clear()
			{
				iterator it = begin();
				while (it != end())
				{
					erase(it++);
				}
			}

			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);
			}

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

				newnode->_next = _head;
				newnode->_prev = tail;
				tail->_next = newnode;
				_head->_prev = newnode;
			}

		private:
			Node* _head;
		};
	};

	void Test_list1()
	{
		list<int> l;
		l.push_back(1);
		l.push_back(2);
		l.push_back(3);
		l.push_back(4);

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

	struct Date
	{
		int _year;
		int _month;
		int _day;

		Date(int year = 0,int month = 1,int day = 1)
			:_year(year)
			,_month(month)
			,_day(day)
		{}
	};

	void Test_list2()
	{
		list<Date> l;
		l.push_back(Date(2006,9,12));
		l.push_back(Date(1999,5,6));

		list<Date>::iterator it = l.begin();
		while(it != l.end())
		{
			cout << it->_year << "-" << it->_month << "-" << it->_day << endl;
			++it;
		}
	} 

	void list_print(const list<int>& l)
	{
		list<int>::const_iterator it = l.begin();
		while (it != l.end())
		{
			//*it = 1;
			cout << *it << " ";
			++it;
		}
		cout << endl;
	}

	void Test_list3()
	{
		list<int> l;
		l.push_back(1);
		l.push_back(2);
		l.push_back(3);
		l.push_back(4);
		l.push_back(5);

		list_print(l);
	}
}

int main()
{
	wkl::Test_list3();
	return 0;
}

新手写博客,有不对的位置希望大佬们能够指出,也谢谢大家能看到这里,让我们一起学习进步吧!! 

  • 12
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值