C++之迭代器分类与List容器的使用

目录

迭代器的分类

List容器

​编辑

总结


在Vector容器中我们学习了迭代器,知道了迭代器的作用和使用方法,本期我们将进一步学习迭代器的概念以及list容器的使用。

迭代器的分类

以算法库中的两个算法为例:

sort算法是用来排序的,reverse算法是用来进行容器的逆置,但是们发现了两个类似迭代器Iterator的东西,但是又与我们之前看到的迭代器不相同,那么这两个迭代器究竟是什么呢?下来为大家一一介绍。 

声明:所有迭代器都是模板类型,所以站在语法层面,所有的迭代器变量都可以作为实参传给迭代器类型,但是在使用的角度这是行不通的,什么类型的迭代器,就应该传什么类型的迭代器变量。

1.只读/只写迭代器(output_iterator/input_iterator)

 这种迭代器并没有实际对应的类型,我们可以认为,这种迭代器是最基本的类型,其它所有的迭代器都是从此迭代器衍生出来的。

2.单向迭代器(forward_iterator)

单向迭代器,其实就只能进行迭代器的++操作,最典型的就是forward_list,unordered_set和unorder_map容器。

3.双向迭代器(bidirectional_iterator)

双向迭代器,其实就是可以进行迭代器的++和--操作,最典型的就是list,map和set容器。

4.随机迭代器(randomaccess_iterator) 

随机迭代器,其实就是可以进行迭代器的++,--,+和-操作,最典型的就是deque,vector和string。

其实不难发现,往下的每个迭代器都是对上述每个迭代器功能的补充,这个就像后期我们学习到的继承的概念,子类可以继承父类的属性,也有自己独有的属性。继承中还有一个很重要的概念就是切片,这个内容我们后期会为大家讲解,现在大家只需要记住一个概念即可,子类对象可以传给父类对象,但是父类对象不能传给子类对象。所以整个关系图如下图所示。

 所以模板如果是父类,那么父类之后所有的子类对象都可以进行传递,付过模板是子类,那么子类之前的父类是不能进行传递的。

reverse函数需要传递的参数类型应该是双向迭代器,但是由于随机迭代器是它的子类,所以也可以传随机迭代器,我们知道vector是随机迭代器所以用vector容器进行验证;由于单向迭代器是它的父类,所以不能传单向迭代器,我们知道forward_list是单向迭代器,所以我们用forward_list进行验证。

#include<iostream>
using namespace std;
#include<vector>
#include<forward_list>


int main()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
    vector<int>::iterator it1 = v1.begin();
	while (it1 != v1.end())
	{
		cout << *it1 ;
		it1++;
	}
	cout << endl;
	reverse(v1.begin(), v1.end());
	vector<int>::iterator it2 = v1.begin();
	while (it2 != v1.end())
	{
		cout << *it2 ;
		it2++;
	}

	forward_list<int> l1;
	l1.push_front(1);
	l1.push_front(2);
	l1.push_front(3);
	l1.push_front(4);
	forward_list<int> ::iterator it3 = l1.begin();
	while (it3 != l1.end())
	{
		cout << *it3;
		it3++;
	}
	cout << endl;
	reverse(l1.begin(), l1.end());
	forward_list<int>::iterator it4 = l1.begin();
	while (it4 != l1.end())
	{
		cout << *it4;
		it4++;
	}
	return 0;
}

我们发现,vector容器的元素进行了逆置,也证明了子类可以传给父类。 

我们发现,forward_list容器的元素没有进行逆置, 也证明了父类不能传给子类。

以上便是迭代器分类的所有内容。

List容器

list容器是一个带头双向循环链表。

构造函数

构造函数大家只需要记住,list容器的空间是从空间配置器中申请的,至于空间配置器是什么,这个后期会为大家讲述。list同样可以使用迭代器区间进行构造,但是最有用的就是可以是一个空构造,因为本身已经有了缺省值。 

析构函数

 

 修改函数

 大部分的函数功能与vector容器类似,大家可以查看vector那一章节。但是要注意的是list中没有reserve功能,也就是没有扩容功能,因为list是链表链表的空间是用多少申请多少,不像vector数组,是不管是否使用直接申请一大块空间。

迭代器

迭代器的使用也与vector类似,大家可以参考vector的使用。

其实大家不妨仔细思考一下,这个begin和rebegin究竟有什么关系呢?

其实只要是双向迭代器或者是双向迭代器的子类都有这个功能,单向迭代器即双向迭代器的父类是没有这个功能的。

单向迭代器,forward_list容器的迭代器如下图。

 随机迭代器,vector容器的迭代器如下图。

查看文档之后,确实是这样的,究竟是为什么呢?

其实我们一开始就已经讲述了这个问题的答案,因为单向迭代器是不支持--操作的,双向迭代器和随机迭代器是支持--操作的,所谓的rebegin其实就是把正向迭代器的end作为了begin然后进行--,又把--封装成了++。但是单向迭代器是没有--操作的,所以不支持反向迭代器。

总的来说,stl库底层会对每个容器的功能进行封装,最后形成用户层看着类似的接口,所以只要学习了一个容器的接口之后,学习其它的容器的接口不过是照猫画虎,很容易上手。

总结

本期的内容主要讲解了迭代器的分类和list的基本使用,主要是迭代器的分类,总共分为四类,只读只写迭代器,单向迭代器,双向迭代器,随机迭代器。大家其实只需要记得它们的父子关系即可,在今后遇到模板传参的问题时,记住一句话“子类可以传给父类,但是父类不能传给子类”。list的基本操作其实和vector很相似,因为它们的接口都进行了封装,list的重点是下期我们要学习模拟实现。

本期内容到此结束^_^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

棠~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值