C++ STL反向迭代器的实现

 更新时间:2022年07月26日 11:43:52   作者:酬 勤  
本文主要介绍了C++ STL反向迭代器的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

反向迭代器其实就行对正向迭代器进行封装,源生迭代器,为了实现运算符的结果不同,正向迭代器也对源生迭代器进行了封装。

反向迭代器的适配器,就是 Iterator是哪个容器的迭代器,reverse_iterator < Iterator >就可以 适配出哪个容器的反向迭代器。复用的体现。

反向迭代器适配器结构:

	template <class Iterator, class Ref, class Ptr>
	class reverse_iterator
	{
		typedef reverse_iterator<Iterator, Ref, Ptr> self;
	public:
	// 重载运算符函数
	private:
		Iterator _it;
	};

源码容器获取迭代器时具体情况,如图:

在这里插入图片描述

我们以为的情况:

在这里插入图片描述

这是源码里的实现的大概情况,begin()与rend()对称,end()与rbegin()对称。这与我们想的不一样,所以反向迭代器适配器内部实现的也有所不一样。例如:
如果我们按照源码的思路写,反向迭代器里封装了一个正向迭代器_it,正常的++,–等操作只需要调用_it的–,++运算符重载函数即可。除了,operator*需要特写,如下代码:

		Ref operator*()
		{
			//正常思路
			//return *_it;
			// 源码思路
			Iterator prev = _it;
			return *--prev;
		}

正常情况是解引用迭代器,但是源码的思路是往后一个位置的迭代器才是。这也是因为rbegin,和rend实现的原因导致的。

适配出来的反向迭代器其用法和正向迭代器一样;

反向迭代器根正向迭代器区别就是++、–的方向是相反的所以反向迭代器封装正向迭代器即可,重载控制++、–的方向。
源码的设计追求对称,我们设计可以不按源码走,在容器实现rbegin(),rend()时,要按照反向迭代器的设计风格去实现。

list完整样例:

1、反向迭代器适配器

	// Iterator是哪个容器的迭代器,reverse_iterator<Iterator>就可以
	// 适配出哪个容器的反向迭代器。复用的体现
	template <class Iterator, class Ref, class Ptr>
	class reverse_iterator
	{
		typedef reverse_iterator<Iterator, Ref, Ptr> self;
	public:
		reverse_iterator(Iterator it)
			:_it(it)
		{}

		Ref operator*()
		{
			//正常思路
			//return *_it;
			Iterator prev = _it;
			return *--prev;
		}

		Ptr operator->()
		{
			return &operator*();
		}

		self& operator++()
		{
			--_it;
			return *this;
		}

		self& operator--()
		{
			++_it;
			return *this;
		}

		bool operator!= (const self& rit) 
		{
			return _it != rit._it;
		}

	private:
		Iterator _it;// 封装任何类型的正向迭代器
	};

二、list 正向迭代器

	// iterator -> 类去分装节点指针,重载*、++ 等运算符,让它们像指针一样使用
	template<class T,class Ref,class Ptr>
	class _list_iterator
	{
	public:
		typedef _list_iterator < T, Ref,Ptr> self;
		typedef ListNode<T> Node;
		_list_iterator( Node* x)
			:_node(x)
		{}
		// ++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->_pre;
			return *this;
		}

		// it--
		self operator--(int)
		{
			self tmp(*this);
			_node = _node->_pre;
			return tmp;
		}

		//*
		Ref operator*()
		{
			return _node->_data;
		}
		//->
		Ptr operator->()
		{
			return &(_node->_data);
		}
		//!=
		bool operator!=(const self& x)
		{
			return _node != x._node;
		}
		//==
		bool operator==(const self& x)
		{
			return _node == x._node;
		}

		Node* _node;
	};

三、 list容器
注意:这里只涉及反向迭代器的内容

template<class T>
	class list
	{
	public:
		typedef ListNode<T> Node;
		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());
		}
		const_reverse_iterator rbegin()const
		{
			return const_reverse_iterator(end());
		}
		reverse_iterator rend()
		{
			return reverse_iterator(begin());
		}
		const_reverse_iterator rend()const
		{
			return const_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->_pre = _head;
		}
		

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

	private:
		Node* _head;// 头结点指针
	};

测试代码:

	void test11()
	{
		BBQ::list<int> L1;
		L1.push_back(1);
		L1.push_back(2);
		L1.push_back(3);
		reverse_print_list(L1);
	}

到此这篇关于C++ STL反向迭代器的实现的文章就介绍到这了,更多相关C++ STL反向迭代器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++ push方法与push_back方法常见方法介绍

    C++ push方法与push_back方法常见方法介绍

    push与push_back是STL中常见的方法,都是向数据结构中添加元素,本文还将简述push对应的stack与queue系列,常见方法的介绍,以及与push_back相对应的vector系列常见方法介绍,感兴趣的朋友跟随小编一起看看吧
    2022-11-11
  • C++ 三种继承方式及好处示例详解

    C++ 三种继承方式及好处示例详解

    这篇文章主要为大家介绍了C++ 三种继承方式及好处示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • 浅析C++中的间接宏函数

    浅析C++中的间接宏函数

    这篇文章主要介绍了C++中的间接宏函数,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • 老生常谈C++ 中的继承

    老生常谈C++ 中的继承

    这篇文章主要介绍了C++ 中的继承,本文通过实例代码给大家介绍的非常详细对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • 详解c++ atomic原子编程中的Memory Order

    详解c++ atomic原子编程中的Memory Order

    在多核编程中,我们使用内核对象【如:事件对象(Event)、互斥量对象(Mutex,或互斥体对象)、信号量对象(Semaphore)等】来避免多个线程修改同一个数据时产生的竞争条件。本文将详细介绍c++ atomic原子编程中的Memory Order。
    2021-06-06
  • C语言变长数组 struct中char data[0]的用法详解

    C语言变长数组 struct中char data[0]的用法详解

    下面小编就为大家带来一篇C语言变长数组 struct中char data[0]的用法详解。小编觉得挺不错的现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • C++11中std::async的使用详解

    C++11中std::async的使用详解

    这篇文章主要介绍了C++11中std::async的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • codeblocks安装及使用超详细图文教程

    codeblocks安装及使用超详细图文教程

    这篇文章主要介绍了codeblocks安装及使用教程详解,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-01-01
  • c语言尾队列tailq使用示例分享

    c语言尾队列tailq使用示例分享

    这篇文章主要介绍了c语言尾队列tailq使用示例,大家参考使用吧
    2014-01-01
  • C++类的分离式写法介绍示例

    C++类的分离式写法介绍示例

    今天小编就为大家分享一篇关于C++类的分离式写法介绍示例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12

最新评论