C++迭代器浅析

迭代器是什么

迭代器是指向元素范围(如数组或容器)中的某个元素的任何对象,它能够使用一组运算符(至少包括++和&运算符)遍历该范围的元素。

迭代器最明显的形式是指针:指针可以指向数组中的元素,并可以使用++循环访问它们。每个容器类型都有一个特定的迭代器类型,用于循环访问其元素。

迭代器一般实现为容器的嵌套类型,在容器内部提供具体的实现。但是容器不同,底层元素遍历的方式也不同,迭代器提供常用的operator!=,operator++,operator*等运算符的重载函数,将迭代器封装在运算符重载中,在用户端的使用方式上是一致的,但是底层的实现方式并不相同

迭代器按照定义分为以下四种

1) 正向迭代器

容器类名::iterator  迭代器名;


2) 常量正向迭代器

容器类名::const_iterator  迭代器名;


3) 反向迭代器

容器类名::reverse_iterator  迭代器名;


4) 常量反向迭代器

容器类名::const_reverse_iterator  迭代器名;

迭代器作用

通过迭代器可以读取它指向的元素,*迭代器名就表示迭代器指向的元素。通过非常量迭代器还能修改其指向的元素。

迭代器都可以进行++操作。反向迭代器和正向迭代器的区别在于:

  • 对正向迭代器进行++操作时,迭代器会指向容器中的后一个元素;
  • 而对反向迭代器进行++操作时,迭代器会指向容器中的前一个元素。
void test_3()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(3);
	v1.push_back(5);
	v1.push_back(7);
	v1.push_back(9);

	vector<int>::iterator it = v1.begin();//正向迭代器
	while (it != v1.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;


	auto rit = v1.rbegin();//反向迭代器
	while (rit != v1.rend())
	{
		cout << *rit << " ";
		rit++;
	}
	cout << endl;
}

 常量迭代器与普通迭代器区分

1.typedef T* iterator;
2.typedef const iterator const_iterator;
3.typedef const T* const_iterator;
方式1方式2方式3
说明迭代器的本质上是一个指针相当于T* const。const修饰iterator,说明iterator本身不可被修改,迭代器指向的内容可以被修改const修饰T*,说明指针指向的内容不可以被修改,但是迭代器还是可以进行++等操作

因此普通迭代器的实现用方式1实现,常迭代器用方式3实现。

方式二的实现方式是错误的

反向迭代器

正向迭代器与反向迭代器的并没有很大的区别,区别在于++、--的反向不同

//迭代器是原生指针或者是自定义类型
	//普通迭代器类
	template<class T,class Ref,class Ptr>
	//Ref与Ptr是为了适用常量迭代器,Ref=T&	Ptr=T*
	struct __list_iterator
	{
		typedef list_node<T> node;
		typedef __list_iterator<T,Ref,Ptr> self;//类对象本身
		node* _node;

		__list_iterator(node* n)//迭代器初始化
			:_node(n)
		{}

		Ref operator* ()
		//常量迭代器与普通迭代器只有返回值不同
		{
			return _node->_data;
		}
		Ptr operator->()
		{
			return &_node->_data;
		}

		self& operator++()//返回迭代器类对象
		{
			_node = _node->_next;
			return *this;
		}
		self& operator++(int)//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& li)
		{
			return _node != li._node;
		}
		bool operator==(const self& li)
		{
			return _node == li._node;
		}
	};



typedef __list_iterator<T, const T&, const T*>reverse_iterator;//反向迭代器


reverse_iterator rbegin () { return reverse_iterator(_head->_prev); }
reverse_iterator rend() { return reverse_iterator(_head); }

对于如上的代码

 STL库中尽可能使得代码简洁高效,因此会将正向迭代器和反向迭代器设计的尽可能相像

因此需要模拟实现反向迭代器,下面以list容器为例

#pragma once

namespace my_iterator
{
	template<class Iterator,class Ref,class Ptr>
	struct ReverseIterator
	{
		typedef ReverseIterator<Iterator,Ref,Ptr> Self;
		Iterator _cur;

		ReverseIterator(Iterator it)
			:_cur(it)
		{

		}

		Ref operator*()
		{
			Iterator tmp = _cur;//由于是反向得,因此是正向迭代器对应得前一个位置
			--tmp;
			return *tmp;
		}

		Self& operator++()
		{
			--_cur;
			return *this;
		}

		Self& operator++(int)
		{
			--_cur;
			return *this;
		}

		Self& operator--()
		{
			++_cur;
			return *this;
		}

		Self& operator--(int)
		{
			++_cur;
			return *this;
		}

		bool operator!=(const Self& s)
		{
			return _cur != s._cur;
		}
	};
}

typedef ReverseIterator<iterator, T&, T*>reverse_iterator;//反向迭代器
typedef ReverseIterator<iterator, const T&, const T*> const_reverse_iterator;//反向迭代器

reverse_iterator rbegin () { return reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值