左耳听风_032_31_编程范式游记2-_泛型编程

你好,我是陈浩网名英,做耳朵house.在上一节课中呢,我们从c语言开始说起,聊了聊面向过程式的辩证范式。

那相信从代码的角度呢,你对这种类型的语言啊已经有了一些理解。

那作为一门高级语言呢,c语言啊它绝对是编程语言历史发展过程中的一个重要里程碑。

但是随着认知的升级呢,面向过程的c语言啊已经无法满足更高层次的编程的需要。

于是呢c加加就出现了。

那一九八零年ATT贝尔实验室的biononor straw strope创建的c加加语言横空出世,它既可以全面兼容c语言,又巧妙的柔和了一些面向对象的编程理念。

那现在来看,不得不佩服他的魄力。

那在这里呢我也向你推荐一本书,那书名是c加加参考资料:https://51gx.top/detail/256语言的设计和演化。

那这本书呢系统介绍了c加加诞生的背景和初衷。

那书的作者呢就是stropfoop本人。

所以你可以非常详细的从语言创建者的角度啊,了解他的设计思路和创新之旅。

当然呢就是在今天啊c加加这门语言啊仍然还有很多争议。

那这里里呢我就细细说,那那果果感兴趣的话,可以看一看我几年前在库壳上发表的文章c加加的坑真的多么?那从语言的角度上来说呢,呃实际上早期的c加加的许多工作啊都是对c的强化和进化,并且呢把完全兼容c啊作为强制性的要求啊,这也是c加加复杂晦涩的原因。

在这一点上呢,java就干的比c加加彻底的多。

在c八九、c九九这两个c语言的标准中呢,有许多改进啊,都是从c加加中引进的。

可见呢c加加对c语言的贡献非常大。

是的,因为c加加很大程度上就是用来解决c语言中的各种问题和各种不方便的。

比如首先啊他用了引用来解决指针的问题。

那第二呢,他用了name space来解决命名空间充足的问题。

那第三呢,他通过try catch来解决检查返回值编程的问题。

那第四呢,他用class来解决对象的创建、复制和销毁的问题,从而可以解决在结构底嵌套的时候可以深度复制的内存安全问题。

那第五呢,他通过重载操作符来实现操作上的泛醒,比如消除了上一讲中提到的比较函数,compare function.那再比如用一位操作符来消除print f函数的数据类型,不够泛型的问题。

那第六呢,它通过模板template,虚函数的多态和运行式识别,来达到更高层次的泛型和多态。

那第七呢,他用RARI和智能指针的方式解决了c语言装啊,因为需要释放资源而出现的那些非常ugly啊,也很容易出错的代码的问题。

那第八点呢,他用STL解决了c语言中算法和数据结构的n多种抗衡。

那c加加呢是支持编程范式最多的一门语言。

它虽然解决了很多c语言的问题啊,但我个人觉得它最大的意义呢是解决了c语言泛型编程的问题。

因为我们可以看到一些c加加的标准规格,说明数量有一半以上都在说明STL的标准规格应该是什么样的这说明啊,泛型编程是c加加重点中的重点。

那在理想的情况下呢,算法应该是与数据结构和类型无关的那各种特殊的数据类型,理应做好自己分内的工作。

那算法呢只关心一个标准的实现。

而对于泛型的抽象呢,我们需要回答的问题是,如果我们的数据类型符合通用算法,那么对数据类型的最小需求又是什么呢?我们来看一看c加加它是如何有效解决程序泛型的问题的。

我认为呢有三点。

那第一呢它是通过类的方式来解决。

那类里面呢会有构造函数和析构函数,表示这个类的分配和释放,还有它的拷贝构造函数啊,表示对内存的复制,还有重在操作符啊,像我们呢要去比较大于等于和不等于。

那这样呢就可以让一个用户自定义的数据类型和内建的那些数据类型就很一致了。

那第二呢,它通过模板达到类型和算法的妥协。

那模板呢有点像DSL模板的特化呢,会根据使用者的类型在编缘时期啊生成那个模板的代码。

那模板呢还可以通过一个虚拟类型来做类型绑定。

那这样呢不会导致类型转换时的问题。

所以模板呢就很好的取代了c时代宏定义带来的问题。

第三呢,它引用了虚函数和运行时的类型识别。

虚函数带来的多肽在语义上呢可以支持同一类的类型泛型。

而运行时类型识别技术呢可以做到在泛行时啊,对具体类型的特殊处理。

那这样一来呢就可以写出基于抽象接口的泛型了。

那拥有这些c加加引入的技术呢,我们就可以做到c语言很难做到的泛型编程了。

那正如前面所说过的,一个良好的泛型编程呢,需要解决算法的泛型类型的泛型,属据结构的泛型啊,这几个泛型编程的问题,就像前面介绍过的函函,我拿它啊,举个例子里面的searfor int i等于零,i小于line i加加。

这样的遍历方式呢只能适用于顺序型的数据结构的迭代啊,比如array、 set、 hill list,还有link等等。

它并不适用于非顺序型的数据结构啊,比如哈希表啊、二叉树啊,还有图啊等等。

数据不是按顺序存放的数据结构。

所以呢如果找不到一种泛型的数据结构的操作方式,包括遍历啊查找啊,增加删除和改等等。

那么任何的算法或者程序啊都不可能做到真正意义上的泛型。

那除了lserge函数这样的遍历操作之外呢,还有serge函数的返回值,而是一个整型的索引结构。

它并个整形的下标呢,对于顺序型的数据结构啊是没有问题的那是对于非顺序型的数据结构呢在语义上都存在问题。

比如我要在一个harsh table中查找一个key,那应该返回什么呢?一定不是返回索引下标。

因为在hash table这样的数据结构中呢,数据的存放位置啊不是顺序的。

而且呢还会因为容量不够的问题被重新哈希后改变,所以呢返回数组下标啊是没有意义的。

对此呢我们要把这个事儿做的泛型和通用一些。

如果找到了这个元素呢,就返回它的一个指针啊,会更靠谱一些。

所以呢为了解决泛型的问题,我们需要动用以下两个c加加的技术。

第一呢是使用模板技术来抽象类型。

那这样呢就可以写出类型无关的数据结构。

那第二呢是使用一个迭代器来便利或者操作数据结构内的元素。

那这样呢我们就把c语言的设置函数啊改造成了c加加泛型版本的设置函数啊,你可以去文中看一下。

在c加加的泛型版本中呢,我们可以看到它使用了type name t抽象了数据结构中存储数据的类型。

它还使用了type name eter.那这个呢是不同数据结构需要自己实现的迭代器。

那这样呢也就抽象掉了不同类型的数据结构。

然后呢我们对数据容器的便利啊,使用了特尔中的加加方法。

那这个呢是数据容器,需要自己重载的操作符,这样通过操作符重载啊,也就泛型叫做便利。

同时呢在函数的入参上,它使用了p start和p and来表示遍历的起止。

另外呢它还使用新eter来取得这个指针的内容。

那这个呢也是通过重载星号啊,也就是取值操作符来达到的泛型。

当然啊你可能会问,为什么我们不用标准接口,点点eanext来取代加加,用eter点get value来取代星号,而是要重载操作符呢?那其实这样做呢是为了兼容原有c语言的编程习惯。

那在这里呢我要说明一下,所谓的eter呢,在实际的代码中啊,就是像vector类里面的iterator啊,或者是map类里面的initerator这样的东西。

那这个呢是由相应的数据容器来实现和提供的。

我们可以对比一下CI加STL标准库中find的这个函数的代码实现。

也许你觉得到这一步,我们的泛型设计就完成了。

其实呢这还远远不够,四sh函数呢只是一个开始,我们还有别的算法会让问题啊变得更加复杂。

我们再来看一个sum求和函数。

那同样呢我们在文中呢把c语言版本的sum实现改造成了c加加泛型版本的实现。

那从代码中你看到什么问题了吗?这个代码中最大的问题呢就是t result等于零这套语句。

那这个零呢它假设的返回值的类型啊是个int.这个t呢它假设了英特尔中出来的类型是个t那这样的假设呢是有问题的,如果类型不一样,就会导致转型的问题。

那这样呢会带来非常八个里的代码,那么我们应该怎么解决呢?那这个呢就需要用到c加加泛型编程的重要技术啊,也就是迭代器了。

我们知道itter在实际调用者那里啊,会是一个具体的啊像vector、 int、 iterator这样的东西。

那在这个声明中呢,int它已经被传入eter中了。

所以呢定义result的t应该可以从eter中来。

那这样呢就可以保证类型是一样的,而且啊不会有被转型的问题。

所以呢我们需要精心的实现一个迭代器。

因为c加加STL标准库里面的迭代器啊太过复杂,所以我在文中呢写了一个精简版的迭代器,我没有把所有的代码列出来,而是把它的一些基本思路列了出来。

那这里呢我说明一下几个关键点。

首先呢一个迭代器需要和一个容器在一起,因为这里面啊是对这个容器的具体的代码实现。

那其次呢,它需要重载一些操作符,比如取值操作、成员操作,还有比较操作,还有便利操作等等。

那还有呢它还有type dif一些类型,比如value type啊,告诉我们容器里数据的实际类型是什么样子。

那还有一些比如begin和and的基本操作,我们还可以看到其中呢有一个point ter PTR的内部指针来指向当前的数据。

好了,有了这个迭代期之后呢,我们还要解决t result等于零啊,后面的这个零的问题。

那这个事儿呢算法没有办法搞定,最好由用户来传入。

于是呢就出现了文中这个最终版本的泛型sum函数,我们可以看到type name eter value, type result t等于unit啊,这条语句啊是关键。

那这样呢我们就解决了所有的问题。

那这个萨姆求和函数呢,我们可以像文中这样来使用它。

那以上呢就是整个STL的泛型方法。

其中呢包括泛型的数据容器和泛型数据容器的迭代器。

那有了这些之后呢,泛型的算法就很容易写了。

但是呢还能不能做到更加抽象,更为泛型呢?比如我们有一个数据结构,employee里面有一个vacation成员变量啊,表示休假了多少天,还有工资、salary.那现在呢我想计算员工的总薪水或者总休假天数,那这样呢我们的萨玛就完全不知道该怎么搞了,因为要累加的是employee中的不同字段。

那即便我们的in葡OE重载了,加号操作,那也不知道要加哪个字段。

那另外呢我们还可能会求平均值average,求最小值min,求最大值max,求中位数mean等等。

你会发现算法写出来啊基本上都是一样的啊,只是其中的累加操作变成了另外一个操作。

就这个例子来说呢,我想计算员工薪水里面最高的和休假最少的,或者呢我想计算全部员工总共休假了多少天。

那么面对这么多的需求,我们是否可以泛醒一些呢?怎么解决这些问题呢?那要解决这个问题呢,我希望我的这个算法只管遍地。

那具体要干什么呢?那是业务逻辑,由外面的调用方来定义就好了,和我无关。

那这样一来呢,代码的通用度啊就更高了。

那这样呢就有了一个抽象程度更高的版本。

那代码呢我放到了文章里,那这个版本呢再叫萨m就不太合适了。

那这个版本呢应该是reduce用于把一个数组啊reduce成一个值。

在这个版本的代码中呢,我们需要传一个函数进来。

在STL中呢,它是一个函数对象啊,我们还是这套算法。

但是result呢不是像前面那样去加,而是把整个迭代器值啊给你一个operation,然后由它来做。

那我把这个方法又拿出去了,所以呢就会变成这个样子。

在c加加STL中呢,与我这个reduce函数对应的函数呢名字叫cumulate.那它的实际代码呢有两个版本,那这两个版本啊我在文中都给你写了出来。

那其中第一个版本呢,只不过是把well语句换成了for语气。

而第二个版本呢更为抽象,因为我需要传入一个二元操作函数、finanary、 operation OP来做accumulate, accumulate的语义啊,比sam更抽象了。

那这样呢我就可以像文中这样用这个radio参数来获取员工的总薪水和最高薪水了。

呃,需要注意啊,我在这里呢用了c加加的兰姆达表达式,你可以很清楚的看到reduce这个函数呢就更通用了。

具体要干什么样的事情呢?放在匿名函数里面,那它会定义我要做什么?我呢只做一个reduce,那更抽象一点来说呢,我只是把一个数组一个集合变成一个值。

那么怎么变成一个值呢?由这个函数啊来决定我们来看一看啊如何使用reduce和其他的函数,完成一个更为复杂的功能。

再来看文中这一段示例代码,我先定义了一个函数对象counter.那这个函数对象呢需要一个叫count的函数对象,呃,它是一个条件判断函数,如果满足条件呢则加一,否则呢就加零。

然后呢,我用上面的counter函数对象和reduce函数共同来打造一个counter if算法,你可以看到只需要一行代码就可以实现了。

那至于是什么样的条件呢?这属于业务逻辑啊,不是我的流程控制,所以呢这个应该交给使用方。

于是呢当我需要统计薪资超过一万块的员工数量的时候呢,调用这个counter if函数同样只需要一行代码就可以了。

调用reduce的时候呢,可以只对结构体中的某些值做reduce.比如说只对salary大于一万的人做啊,只选出这个里面的值。

那他用reduce啊就可以达到这步。

只要传不同的函数给它啊,你就可以又造出一个新的东西出来。

那说着说着呢,就到了函数式编程。

在函数式编程里面呢,我们可以用很多的像reduce这样的函数来完成更多的像STL里面counter if这样有具体意义的函数。

那关于函数式编程呢,我们会在后面继续具体聊一聊。

好了,这节课到这里呢就结束了。

我们来总结一下今天所讲的内容。

那在这一讲中呢,我们聊到c加加语言是如何通过泛型来解决c语言所遇到的问题。

那其实这里面呢主要就是泛型编程和函数式编程的基本方法相关的细节。

那虽然解决编程语言中类型带来的问题啊,可能有多种方式啊,不一定就是c加加这种方式。

而我之所以从c一和c加加开始,目的呢只是因为c和c加加啊都是比较偏底层的编程语言。

从底层的原理上呢,我们可以更透彻的了解从c到c加的演进,这一过程中带来的编程方式的变化。

这样可以让你看到,在静态类型语言方面,解决泛型编程的一些技术和方法,从而感受到其中的奥妙和原理。

因为形式是多样的,但是呢原理是相通的。

所以呢这个过程啊会非常有助于你更深刻的了解后面会谈到的更多的变成范式。

那文末呢是编程范式游记一系列文章的目录,方便你了解这一系列内容的全貌。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/759761.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

shark云原生-日志管理体系-filebeat

文章目录 1. deploy 文件1.1 RBAC1.2. DaemonSet1.2.1. Elasticsearch 连接信息1.2.2. Volume 1.3. ConfigMap1.3.1. 日志收集路径1.3.2. 日志事件输出目标 2. 在控制平面节点上运行Filebeat3. 查看输出3.1. 关于处理器 processors 4. 日志收集配置4.1. 手动指定日志收集路径4.…

索引:通往高效查询的桥梁(五)

引言 上一章,我们探索了SQL的基础知识,从DDL、DML到DQL,掌握了构建和操作数据库的基本技能。现在,我们将目光转向数据库性能的核心——索引。索引,犹如图书馆中的目录系统,极大地加速了数据检索过程&#…

Unity实现简单的MVC架构

文章目录 前言MVC基本概念示例流程图效果预览后话 前言 在Unity中,MVC(Model-View-Controller)框架是一种架构模式,用于分离游戏的逻辑、数据和用户界面。MVC模式可以帮助开发者更好地管理代码结构,提高代码的可维护性…

CloudFlare Tunnel实现内网穿透

CloudFlare Tunnel 背景: 家中设备处于内网NAT环境,希望使用CF tunnel构建内网穿透的环境。 有了CF tunnel后,可实现: 家中的NAS可以直接SSH AWS的云服务可迁到到NAS NAT主机借助CF tunnel部署服务 步骤: clou…

Mx Admin 基于react18的后台管理系统

前言 Mx Admin 基于React18 vite5 antd5的后台管理系统, 基于RBAC的权限控制系统,动态菜单和动态路由支持tab路由缓存嵌套菜单支持多种菜单布局模式亮暗色主题切换

成为画图大师,用图表讲故事

这些问题你是否遇到过: 项目总结会上,如果用数据呈现你做的价值? 完善详尽的数据分析得出了让人信服的结论,如何呈现在BOSS面前? 我们要的不是数据,而是数据告诉我们的事实 数据很重要,但只是原料,所以…

基于Spring Boot的在线医疗咨询平台的设计与实现【附源码】

基于Spring Boot的在线医疗咨询平台的设计与实现 Design and implementation of the computer hardware mall based on Spring Boot Candidate: Supervisor: April 20th, 2024 学位论文原创性声明 本人郑重声明:所呈交的论文是本人在导师…

(2024,DDPM,DDIM,流匹配,SDE,ODE)扩散:基础教程

Step-by-Step Diffusion: An Elementary Tutorial 公和众与号:EDPJ(进 Q 交流群:922230617 或加 VX:CV_EDPJ 进 V 交流群) 目录 0 前言 1 扩散的基础知识 1.1 高斯扩散 1.2 抽象中的扩散 1.3 离散化 2 随机采样…

【强化学习的数学原理】课程笔记--2(贝尔曼最优公式,值迭代与策略迭代)

目录 贝尔曼最优公式最优 Policy求解贝尔曼最优公式求解最大 State Value v ∗ v^* v∗根据 v ∗ v^* v∗ 求解贪婪形式的最佳 Policy π ∗ \pi^* π∗一些证明过程 一些影响 π ∗ \pi^* π∗ 的因素如何让 π ∗ \pi^* π∗ 不 “绕弯路” γ \gamma γ 的影响reward 的…

qt for android 使用打包sqlite数据库文件方法

1.在使用sqlite数据库时,先将数据库文件打包,放置在assets中如下图: 将文件放置下android中的assets下的所有文件都会打包在APK中,可以用7zip查看apk文件 2.在qt代码读取数据文件,注意在assets下的文件都是Read-Only,需…

[AIGC] Shell脚本在工作中的常用用法

Shell脚本是一种为 shell 编写的脚本程序。商业上的 Unix Shell 一般都配备图形界面,主要包括:Bourne Shell(/usr/bin/sh或/bin/sh)、Bourne Again Shell(/bin/bash)、C Shell(/usr/bin/csh&…

抓紧收藏!7 款令人惊艳的 AI 开源项目

🐼 关注我, 了解更多 AI 前沿资讯和玩法,AI 学习之旅上,我与您一同成长! 🎈 进入公众号,回复 AI, 可免费领取超多实用的 AI 资料 和内容丰富的 AI 知识库地址。 自从去年 AIGC 兴起以来,AI 开源…

【python爬虫实战】爬取豆瓣top250(网站有反爬虫机制肿么办)

关于请求头headers: 值得注意的是,与上一篇 :​​​​​​【python爬虫实战】爬取书店网站的 书名&价格(注释详解)-CSDN博客 爬取书名不同,这次爬取豆瓣网站必须使用“请求头headers”,不然将没有输…

Tomcat的安装和虚拟主机和context配置

一、 安装Tomcat 注意:安装 tomcat 前必须先部署JDK 1. 安装JDK 方法1:Oracle JDK 的二进制文件安装 [rootnode5 ~]# mkdir /data [rootnode5 ~]# cd /data/ [rootnode5 data]# rz[rootnode5 data]# ls jdk-8u291-linux-x64.tar.gz [rootnode5 data]…

通用管理页面的功能实现

在Windows Forms(WinForms)应用程序中,创建一个通用的管理页面通常涉及对数据的增删改查(CRUD)操作,以及一些额外的功能,如数据过滤、排序、导出和导入等。 先看一个仓库管理页面要素。 仓库管…

Tcmalloc工具定位内存泄漏问题

内存泄漏问题定位 gperftools工具安装 执行如下操作: git clone https://github.com/gperftools/gperftools.git 注:如果网速较慢,可直接去下载压缩包。 如我下载的地址:https://github.com/gperftools/gperftools/releases/ta…

ComfyUI局部重绘的四种方式 (附件工作流在最后)

前言 局部重绘需要在图片中选择重绘区域,点击图片右击选择Open in MaskEditor(在蒙版编辑器中打开),用鼠标描绘出需要重绘的区域 方式一:重绘编码器 这种方式重绘比较生硬,需要额外搭配使用才行 方式二&…

Sql审核平台Archery的搭建和简单配置

Sql审核平台Archery的搭建和简单配置 Archery是一个开源的Web应用,基于Python开发,利用Flask作为后端框架,前端采用Vue.js,构建了一个现代化的数据操作界面。提供了SQL审核、数据查询、报表生成等功能,同时支持多种数据…

普元EOS学习笔记-创建精简应用

前言 本文依旧基于EOS8.3进行描述。 在上一篇文章《EOS8.3精简版安装》中,我们了解到普元预编译好的EOS的精简版压缩包,安装后,只能进行低开,而无法高开。 EOS精简版的高开方式是使用EOS开发工具提供的IDE,创建一个…

【C语言】指针剖析(完结)

©作者:末央& ©系列:C语言初阶(适合小白入门) ©说明:以凡人之笔墨,书写未来之大梦 目录 回调函数概念回调函数的使用 - qsort函数 sizeof/strlen深度理解概念手脑并用1.sizeof-数组/指针专题2.strlen-数组/指针专题 指针面试题专题 回调函…