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反向迭代器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解C++ 的STL迭代器原理和实现

    1. 迭代器简介 为了提高C++编程的效率,STL(Standard Template Library)中提供了许多容器,包括vector.list.map.set等.然而有些容器(vector)可以通过下标索引的方式访问容器里面的数据,但是大部分的容器(list.map.set)不能使用这种方式访问容器中的元素.为了统一访问不同容器时的访问方式,STL为每种容器在实现的时候设计了一个内嵌的iterator类,不同的容器有自己专属的迭代器(专属迭代器负责实现对应容器访问元素的具体细节),使用迭代

  • 浅谈c++ stl迭代器失效的问题

    之前看<C++ Primier>的时候,也解到在顺序型窗口里insert/erase会涉及到迭代器失效的问题,并没有深究.今天写程序的时候遇到了这个问题. 1 莫名其妙的Erase 最初我的程序是酱紫的,别说话,我知道这样是有问题的,可这样是最直观的想法 int arr[]={0,1,2,3,4,5,6,7,8,9,10}; vector<int> a(arr,arr+sizeof(arr)/sizeof(*arr));for (auto it = a.begin(); it !=

  • C++浅析STL 迭代器 容器的使用

    目录 STL定义 STL六大组件 vector vector嵌套容器 STL定义 STL(Standard Template Library 标准模板库) STL从广义上分为:容器(container) 算法(algorithm) 迭代器(iterator) 容器和算法之间通过迭代器进行无缝连接 STL几乎所有的代码都采用了模板类或者模板函数 STL六大组件 STL大体分为六大组件,分别是: 容器.算法.迭代器.仿函数.适配器.空间配置器 1.容器: 各种数据结构,如vector.list.de

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

    反向迭代器其实就行对正向迭代器进行封装,源生迭代器,为了实现运算符的结果不同,正向迭代器也对源生迭代器进行了封装. 反向迭代器的适配器,就是 Iterator是哪个容器的迭代器,reverse_iterator < Iterator >就可以 适配出哪个容器的反向迭代器.复用的体现. 反向迭代器适配器结构: template <class Iterator, class Ref, class Ptr> class reverse_iterator { typedef reverse

  • C++ 标准模板库 STL 顺序容器详解

    C++ 标准模板库 STL 顺序容器 容器 数据结构 顺序性 重复性 支持迭代器 vector 动态数组 无序 可重复 随机访问迭代器 deque 双向队列 无序 可重复 随机访问迭代器 list 双向链表 无序 可重复 双向迭代器 动态数组 vector ​ vector #include <vector> 动态数组:其元素在内存中是连续存放的,随机存取任何元素都可以在常数时间内完成,在该容器的尾部增删元素也几乎能够在常数时间内完成具有较好的性能. ​ 一个 vector 常用函数使用实例如

  • C++迭代器iterator详解

    目录 1.迭代器分类 1) 正向迭代器 2) 常量正向迭代器 3) 反向迭代器 4) 常量反向迭代器 2.迭代器用法示例 3.迭代器:++it 与 it++ 哪个好? (1)前置返回一个引用,后置返回一个对象 (2)前置不会产生临时对象,后置必须产生临时对象,临时对象会导致效率降低 4.迭代器的功能分类 5.迭代器的辅助函数 总结 1.迭代器分类 要访问顺序容器和关联容器中的元素,需要通过"迭代器(iterator)"进行.迭代器是一个变量,相当于容器和操纵容器的算法之间的中介.迭代器

  • C++中的STL中map用法详解(零基础入门)

    目录 一.什么是 map ? 二.map的定义 2.1 头文件 2.2 定义 2.3 方法 三.实例讲解 3.1 增加数据 3.2 删除数据 3.3 修改数据 3.4 查找数据 3.5 遍历元素 3.6 其它方法 四.总结 map 在编程中是经常使用的一个容器,本文来讲解一下 STL 中的 map,赶紧来看下吧! 一.什么是 map ? map 是具有唯一键值对的容器,通常使用红黑树实现. map 中的键值对是 key value 的形式,比如:每个身份证号对应一个人名(反过来不成立哦!),其中

  • C++ STL标准库std::vector的使用详解

    目录 1.简介 2.使用示例 3.构造.析构.赋值 3.1std::vector::vector构造函数 3.2std::vector::~vector析构函数 3.3std::vector::operator=“=”符号 4.Iterators迭代器 4.1std::vector::begin 4.2std::vector::end 4.3std::vector::rbegin 4.4std::vector::rend 4.5std::vector::cbegin(C++11) 4.6std:

  • C++STL之string类的使用

    目录 1.STL简介 (1)什么是STL (2)STL的版本 (3)如何学习STL (4)STL的六大组件 2.string类的基本概念 (1)含义 (2)使用方法 (3)原理 3.string类中常见构造函数 4.string类中析构函数 5.string类对象的容量操作 (1)显示容量 (2)扩容 6.string类中operator[]重载 (1)举例 (2)底层实现 7.string类与迭代器 (1)举例 (2)反向迭代器 (3)使用迭代的意义 (4)补充:语法糖实现遍历 8.strin

  • STL中的string你了解吗

    目录 模拟实现一个string类 成员变量 构造函数 遍历 与容量相关的成员函数 运算符的重载 修改器 常用的几个字符串函数 总结 STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架. STL的六大组件:容器.迭代器.适配器.空间配置器.仿函数.算法. string的行为与普通容器类似,但是并不能说它是个容器,因为无法接受所有类型的数据. string是表示字符串的字符串类. s

  • C++深入分析STL中map容器的使用

    目录 1.map容器 2.map容器原理 3.map容器函数接口 4.使用示例 1.map容器 map是C++ STL的一个关联容器,它提供一对一的数据处理能力.其中,各个键值对的键和值可以是任意数据类型,包括 C++ 基本数据类型(int.double 等).使用结构体或类自定义的类型. 第一个可以称为关键字(key): 第二个可能称为该关键字的值(value): 该容器存储的都是 pair<const K, T> 类型(其中 K 和 T 分别表示键和值的数据类型)的键值对元素. 使用 ma

  • C++  STL _ Vector使用及模拟实现

    目录 1.Vector的介绍 1.1 Vector的介绍 2.Vector的使用 2.1 vector的定义 2.2 vector 迭代器的使用 2.3 vector的空间增长问题 3. vector的增删查改 3.1 push_back (重点) 3.2 pop_back (重点) 3.3 insert 3.4 erase 3.5 operator [ ] 1.Vector的介绍 1.1 Vector的介绍 ​ ​vector官方文档介绍​​ 1.vector是表示可变大小数组的序列容器. 2

随机推荐