当前位置: 首页 > article >正文

[C++]深入剖析list类中迭代器的封装

list迭代器的封装

  • 由浅入深:从底层设计开始分析
    • 1. 设计一个list类
      • list类包括:iterator类和node类(节点类)
      • iterator类不具有const的性质
    • 2.如何让迭代器具有const类型
      • 分析目前的类实现
      • 开始对iterator迭代器进行const设计
        • ①.直接在list类里的替换里加const:
        • ②设计一个新的``const_iterator类``,让const类型的迭代器有专门的类使用
        • ③[最优解法]直接用``模板``的知识
    • [其他]关于迭代器使用->操作符时,编译器的自动优化

由浅入深:从底层设计开始分析

1. 设计一个list类

  • 如果要设计一个list类,我们需要明白以下几点:
    1.list是一个带头双向循环链表
    2.list类的迭代器不是原生指针,是封装过后的指针,通常情况原生指针只适合连续的内存空间
    3.list类的成员只有一个(或者多加一个size成员),该成员通常命名为 _head,是一个哨兵位

list类包括:iterator类和node类(节点类)

--每个节点用list_node类封装
template<class T>
	struct list_node
	{
		list_node<T>* _next = nullptr;
		list_node<T>* _prev = nullptr;
		T _val;

		list_node(T val = T())
			:_val(val)
		{}
	};
	//---------------------------------------------------------------
	template<class T>
	struct list_iterator
	{
		typedef list_iterator<T> self; self就是迭代器本身,只是为了防止频繁地输入
		     						   list_iterator<T>,从而做的优化
		typedef list_node<T> node;
	public:
		node* _pnode;
	};
	//---------------------------------------------------------------
	template<class T>
	class list
	{
		typedef list_node<T> node;
	public:
		typedef list_iterator<T> iterator;
	private:
		node* _head;
		size_t _size;
	};
  • 在这里我们简单实现了一个list类,一个基本的list类包括
  1. list_node节点类
  2. iterator迭代器类

iterator类不具有const的性质

2.如何让迭代器具有const类型

  • 我们在上面迭代器的设计中,并没有直接实现const迭代器,现在让我们来看看目前设计的迭代器

分析目前的类实现

template<class T>
	struct list_iterator
	{
		typedef list_iterator<T> self; self就是迭代器本身,只是为了防止频繁地输入
		     						   list_iterator<T>,从而做的优化
		typedef list_node<T> node;
	public:
		node* _pnode;
	};
	
	在list类中:
	typedef list_iterator<T> iterator;

开始对iterator迭代器进行const设计

现在我们开始设计const类型的迭代器:

①.直接在list类里的替换里加const:
typedef list_iterator<T> iterator;
typedef const list_iterator <T> const_iterator

这种设计和vector有点相似:

vector:
typedef int* iterator;
typedef const int* const_iterator; 

iterator Func(T& 1) || const_iterator Func(T& 1) const  --(判断传入对象是否为const)
  • 但是,这种设计有很大的问题,因为const修饰的不是迭代器指向的内容,而是迭代器本身
    如同const int a一样,const list_iterator<T> const_iterator修饰的不是迭代器指向的空间,而是其本身
  • 如果修饰了迭代器本身,那么将无法实现++/–等基本操作,因此这种写法显然是不合理的
②设计一个新的const_iterator类,让const类型的迭代器有专门的类使用
  • 这种设计虽然能解决问题,但是过于冗余了,为了一个const的迭代器而专门再做一个新的迭代器类,属于吃力不讨好的行为
③[最优解法]直接用模板的知识
list类内:
	typedef list_iterator<T> iterator;
	typedef __list_iterator<const T> const_iterator;

到了这里,问题已经解决了一半
那另外一半呢?

  • 当我们实现迭代器的各种功能时(++/- -/==…),需要用到不同的返回值,例如需要返回T&或是T*
    此时也可以进行对应的优化:
list_iterator类内:
	template<class T, class Ref, class Ptr>
	struct __list_iterator
	{
		typedef list_node<T> Node;
		typedef __list_iterator<T, Ref, Ptr> self;
	};

list类内:
	typedef __list_iterator<T, T&, T*> iterator;
	typedef __list_iterator<T, const T&, const T*> const_iterator;
  • 直接在函数模板把所有需要的返回值都加上,返回的时候给对应的模板类型即可
  • self就是迭代器本身,也是为了不频繁地调用iterator<T, Ref, Ptr>,选择用self简化代码

[其他]关于迭代器使用->操作符时,编译器的自动优化


http://www.kler.cn/a/411314.html

相关文章:

  • 【系统架构设计师】真题论文: 论数据访问层设计技术及其应用(包括解题思路和素材)
  • 基础入门-Web应用架构搭建域名源码站库分离MVC模型解析受限对应路径
  • 【自动化Selenium】Python 网页自动化测试脚本(上)
  • WSL安装不同版本ubuntu(已有ubuntu20.04,再装ubuntu18.04)
  • [M最短路] lc743. 网络延迟时间(spfa最短路+单源最短路)
  • TensorFlow如何调用GPU?
  • HOW - React 状态模块化管理和按需加载(一) - react-redux
  • 【Python中while循环】
  • Spring Boot 整合 ELK 全面指南:实现日志采集、分析与可视化
  • java——利用 Tomcat 自定义的类加载器实现热加载
  • 最长回文子串&多/虚继承
  • 网络安全原理与技术思考题/简答题
  • 1126刷题
  • 堆的实现(完全注释版本)
  • pikachu文件上传漏洞通关详解
  • 利用 Vue 组合式 API 与 requestAnimationFrame 优化大量元素渲染
  • Paddle Inference部署推理(一)
  • QT-installEventFilter
  • GaussDB高智能--库内AI引擎:模型管理数据集管理
  • 蓝桥杯c++算法秒杀【6】之动态规划【下】(数字三角形、砝码称重(背包问题)、括号序列、异或三角:::非常典型的必刷例题!!!)
  • 前端 Vue 3 后端 Node.js 和Express 结合cursor常见提示词结构
  • C语言解析命令行参数
  • xiaolin coding 图解网络笔记——TCP篇
  • 2686694 - 操作方法:MSEG - DBSQL_REDIRECT_INCONSISTENCY
  • 道路机器人识别交通灯,马路,左右转,黄线,人行道,机器人等路面导航标志识别-使用YOLO标记
  • Python毕业设计选题:基于django+vue的期货交易模拟系统的设计与实现