C++ STL初阶(9):list 中关于reverse_iterator的实现

在完成vector和list的iterator相关部分的实践后来完成反向迭代器的实现

1. list的反向迭代器

书接上回,反向迭代器应当重新封装一个类。

反向迭代器和正向迭代器最大的区别就是,反向迭代器是倒着走的,所以最核心的逻辑就是将++封装成--

注意,在写构造函数时,不管之后有没有再自定义类名,构造函数的函数名都最好就写类的原名称

并且在list中要重新命名方便管理:

我们依然是将Ref和Ptr单独传入,方便写出const_reverse_iterator ,不理解这一点的可以走这里:http://t.csdnimg.cn/4ANMr

将代码实现如下:

cpp 复制代码
template <typename T,typename Ref,typename Ptr>
struct  Reverse_ListIterator {
	typedef ListNode<T>  Node;
	typedef Reverse_ListIterator<T,Ref,Ptr>  Self;
	Node* _pnode;
	Reverse_ListIterator(Node* pnode)
		:_pnode(pnode)
	{}

	Self& operator++() {
		_pnode = _pnode->_prev;
		return *this;
	}
	Self operator++(int) {
		_pnode = _pnode->_prev;
		return _self(_pnode->_next);
	}
	Self& operator--() {
		_pnode = _pnode->_next;
		return *this;
	}
	Self operator--(int) {
		_pnode = _pnode->_next;
		return _self(_pnode->_prev);
	}
	Ref operator*() {
		return _pnode->_data;
	}
	Ptr operator->() {
		return &(_pnode->_data);
	}
	bool operator!=(const Self& it) {
		return this->_pnode != it._pnode;
	}

};

2. rbegin rend

在测试代码之前,我们先来使用一下库中的reverse_iterator

将rbegin()的迭代器++后输出的结果是6,说明对rbegin解引用不是头结点

**rbegin解引用对应的就是最后一位有效元素,而++不是++head ,**但是和end返回同样的位置

我们有两种方法,一种是rbegin就不返回end对应的位置,而是end的前一个节点,也就是最后一个有效节点;或者rbegin还是和end返回的同一个位置,但是在解引用------也就是重载*时,让解出来的引用进行--

cpp 复制代码
Ref operator*()
		{
			Iterator tmp = _it;
			return *(--tmp);
		}

++那么到底用哪种更好呢?++

在实现STL的过程中,我们一直强调:++通用性++

对于第一种处理(rbegin就不返回头结点,而是返回头结点的前一个节点 ), 只要自己能控制就行。但是这一套逻辑拉到其他的容器上是不行的。比如vector , 当我们要想在首元素之前再去找一个无效空间(也就是使用rend)就很麻烦。正取的做法是rend返回的就是begin, rbegin返回的就是end,但是rbegin解引用时都往前--一次 ,rend直接不能解引用即可。如果是让rbegin指向最后一个有效元素,那么rend就需要指向首元素之前的无效空间,不好操作。

因此我们需要对解引用和->的重载重新修改 :

测试:

再使用我们自己的:

肯定不能接受end的返回值(尽管他们指向同样的地方),end返回的是一个构造好的正向迭代器而不是一个Node* , 不可能用于构造。并且reverse_iterator和iterator是不同的类,自然是不能赋值的。

我们需要在list中自己实现rbegin和rend

cpp 复制代码
reverse_iterator rbegin() {
	return reverse_iterator(_head);
}
const_reverse_iterator rbegin()const {
	return const_reverse_iterator(_head);
}

这样就成了

相关推荐
煤泥做不到的!7 分钟前
挑战一个月基本掌握C++(第十一天)进阶文件,异常处理,动态内存
开发语言·c++
F-2H9 分钟前
C语言:指针4(常量指针和指针常量及动态内存分配)
java·linux·c语言·开发语言·前端·c++
axxy200038 分钟前
leetcode之hot100---24两两交换链表中的节点(C++)
c++·leetcode·链表
bryant_meng1 小时前
【python】OpenCV—Image Moments
开发语言·python·opencv·moments·图片矩
若亦_Royi2 小时前
C++ 的大括号的用法合集
开发语言·c++
资源补给站3 小时前
大恒相机开发(2)—Python软触发调用采集图像
开发语言·python·数码相机
m0_748247553 小时前
Web 应用项目开发全流程解析与实战经验分享
开发语言·前端·php
6.943 小时前
Scala学习记录 递归调用 练习
开发语言·学习·scala
Aileen_0v03 小时前
【AI驱动的数据结构:包装类的艺术与科学】
linux·数据结构·人工智能·笔记·网络协议·tcp/ip·whisper
是小胡嘛3 小时前
数据结构之旅:红黑树如何驱动 Set 和 Map
数据结构·算法