左耳听风
陈皓
网名“左耳朵耗子”,资深技术专家,骨灰级程序员
立即订阅
40357 人已学习
课程目录
已完结 108 讲
0/6登录后,你可以任选6讲全文学习。
开篇词 | 洞悉技术的本质,享受科技的乐趣
免费
01 | 程序员如何用技术变现(上)
02 | 程序员如何用技术变现(下)
03 | Equifax信息泄露始末
04 | 从Equifax信息泄露看数据安全
05 | 何为技术领导力?
06 | 如何才能拥有技术领导力?
07 | 推荐阅读:每个程序员都该知道的知识
08 | Go语言,Docker和新技术
09 | 答疑解惑:渴望、热情和选择
10 | 如何成为一个大家愿意追随的Leader?
11 | 程序中的错误处理:错误返回码和异常捕捉
12 | 程序中的错误处理:异步编程以及我的最佳实践
13 | 魔数 0x5f3759df
14 | 推荐阅读:机器学习101
15 | 时间管理:同扭曲时间的事儿抗争
16 | 时间管理:如何利用好自己的时间?
17 | 故障处理最佳实践:应对故障
18 | 故障处理最佳实践:故障改进
19 | 答疑解惑:我们应该能够识别的表象和本质
20 | Git协同工作流,你该怎么选?
21 | 分布式系统架构的冰与火
22 | 从亚马逊的实践,谈分布式系统的难点
23 | 分布式系统的技术栈
24 | 分布式系统关键技术:全栈监控
25 | 分布式系统关键技术:服务调度
26 | 分布式系统关键技术:流量与数据调度
27 | 洞悉PaaS平台的本质
28 | 推荐阅读:分布式系统架构经典资料
29 | 推荐阅读:分布式数据调度相关论文
30 | 编程范式游记(1)- 起源
31 | 编程范式游记(2)- 泛型编程
32 | 编程范式游记(3) - 类型系统和泛型的本质
33 | 编程范式游记(4)- 函数式编程
34 | 编程范式游记(5)- 修饰器模式
35 | 编程范式游记(6)- 面向对象编程
36 | 编程范式游记(7)- 基于原型的编程范式
37 | 编程范式游记(8)- Go 语言的委托模式
38 | 编程范式游记(9)- 编程的本质
39 | 编程范式游记(10)- 逻辑编程范式
40 | 编程范式游记(11)- 程序世界里的编程范式
41 | 弹力设计篇之“认识故障和弹力设计”
42 | 弹力设计篇之“隔离设计”
43 | 弹力设计篇之“异步通讯设计”
44 | 弹力设计篇之“幂等性设计”
45 | 弹力设计篇之“服务的状态”
46 | 弹力设计篇之“补偿事务”
47 | 弹力设计篇之“重试设计”
48 | 弹力设计篇之“熔断设计”
49 | 弹力设计篇之“限流设计”
50 | 弹力设计篇之“降级设计”
51 | 弹力设计篇之“弹力设计总结”
52 | 管理设计篇之“分布式锁”
53 | 管理设计篇之“配置中心”
54 | 管理设计篇之“边车模式”
55 | 管理设计篇之“服务网格”
56 | 管理设计篇之“网关模式”
57 | 管理设计篇之“部署升级策略”
58 | 性能设计篇之“缓存”
59 | 性能设计篇之“异步处理”
60 | 性能设计篇之“数据库扩展”
61 | 性能设计篇之“秒杀”
62 | 性能设计篇之“边缘计算”
63 | 区块链技术的本质
64 | 区块链技术细节:哈希算法
65 | 区块链技术细节:加密和挖矿
66 | 区块链技术细节:去中心化的共识机制
67 | 区块链技术细节:智能合约
68 | 区块链技术 - 传统金融和虚拟货币
69 | 程序员练级攻略:开篇词
70 | 程序员练级攻略:零基础启蒙
71 | 程序员练级攻略:正式入门
72 | 程序员练级攻略:程序员修养
73 | 程序员练级攻略:编程语言
74 | 程序员练级攻略:理论学科
75 | 程序员练级攻略:系统知识
76 | 程序员练级攻略:软件设计
77 | 程序员练级攻略:Linux系统、内存和网络
78 | 程序员练级攻略:异步I/O模型和Lock-Free编程
79 | 程序员练级攻略:Java底层知识
80 | 程序员练级攻略:数据库
81 | 程序员练级攻略:分布式架构入门
82 | 程序员练级攻略:分布式架构经典图书和论文
83 | 程序员练级攻略:分布式架构工程设计
84 | 程序员练级攻略:微服务
85 | 程序员练级攻略:容器化和自动化运维
86 | 程序员练级攻略:机器学习和人工智能
87 | 程序员练级攻略:前端基础和底层原理
88 | 程序员练级攻略:前端性能优化和框架
89 | 程序员练级攻略:UI/UX设计
90 | 程序员练级攻略:技术资源集散地
91 | 程序员面试攻略:面试前的准备
92 | 程序员面试攻略:面试中的技巧
93 | 程序员面试攻略:面试风格
94 | 程序员面试攻略:实力才是王中王
95 | 高效学习:端正学习态度
96 | 高效学习:源头、原理和知识地图
97 | 高效学习:深度,归纳和坚持实践
98 | 高效学习:如何学习和阅读代码
99 | 高效学习:面对枯燥和量大的知识
左耳听风
登录|注册

31 | 编程范式游记(2)- 泛型编程

陈皓 2018-01-16
上一篇文章中,我从 C 语言开始说起,聊了聊面向过程式的编程范式,相信从代码的角度你对这类型的语言已经有了一些理解。作为一门高级语言,C 语言绝对是编程语言历史发展中的一个重要里程碑,但随着认知的升级,面向过程的 C 语言已经无法满足更高层次的编程的需要。于是,C++ 出现了。

C++ 语言

1980 年,AT&T 贝尔实验室的 Bjarne Stroustrup 创建的 C++ 语言横空出世,它既可以全面兼容 C 语言,又巧妙揉和了一些面向对象的编程理念。现在来看,不得不佩服 Stroustrup 的魄力。在这里,我也向你推荐一本书,书名是《C++ 语言的设计和演化》。
这本书系统介绍了 C++ 诞生的背景以及初衷,书的作者就是Stroustrup本人,所以你可以非常详细地从语言创建者的角度了解他的设计思路和创新之旅。当然,就是在今天,C++ 这门语言也还有很多争议,这里我不细说。如果你感兴趣的话,可以看看我几年前在酷壳上发表的文章《C++ 的坑真的多吗?》。
从语言角度来说,实际上早期 C++ 的许多工作是对 C 的强化和净化,并把完全兼容 C 作为强制性要求(这也是 C++ 复杂晦涩的原因,这点 Java 就干得比 C++ 彻底得多)。在 C89、C99 这两个 C 语言的标准中,有许多改进都是从 C++ 中引进的。
可见,C++ 对 C 语言的贡献非常之大。是的,因为 C++ 很大程度就是用来解决 C 语言中的各种问题和各种不方便的。比如:
用引用来解决指针的问题。
用 namespace 来解决名字空间冲突的问题。
通过 try-catch 来解决检查返回值编程的问题。
用 class 来解决对象的创建、复制、销毁的问题,从而可以达到在结构体嵌套时可以深度复制的内存安全问题。
通过重载操作符来达到操作上的泛型。(比如,消除《01 | 编程范式游记:起源》中提到的比较函数cmpFn,再比如用>>操作符消除printf()的数据类型不够泛型的问题。)
通过模板 template 和虚函数的多态以及运行时识别来达到更高层次的泛型和多态。
用 RAII、智能指针的方式,解决了 C 语言中因为需要释放资源而出现的那些非常 ugly 也很容易出错的代码的问题。
用 STL 解决了 C 语言中算法和数据结构的 N 多种坑。

C++ 泛型编程

C++ 是支持编程范式最多的一门语言,它虽然解决了很多 C 语言的问题,但我个人觉得它最大的意义是解决了 C 语言泛型编程的问题。因为,我们可以看到一些 C++ 的标准规格说明书里,有一半以上都在说明 STL 的标准规格应该是什么样的,这说明泛型编程是 C++ 重点中的重点。
理想情况下,算法应是和数据结构以及类型无关的,各种特殊的数据类型理应做好自己分内的工作,算法只关心一个标准的实现。而对于泛型的抽象,我们需要回答的问题是,如果我们的数据类型符合通用算法,那么对数据类型的最小需求又是什么呢?
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《左耳听风》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(32)

  • lnydc
    版本一:
    电影(男主,女主) {
            男主杀死了女主
    }

    版本二:
    电影(男主,女主,情节(A,B){A爱上了B}){
            情节(男主,女主)
    }
    2018-02-14
    23
  • kingeasternsun
    《STL源码解析》,《inside c++model》,记得当时啃这两本时经常要感叹怎么设计的这么精妙,了解内部实现方式后,在使用的时候也更加心里有底
    2018-04-12
    9
  • 闫飞
    泛型技术是静态系统所独有的特性,本质上我觉得还是为了兼顾执行效率和编程灵活性,实现零成本抽象这一刀尖上跳舞的巨大挑战。

    较新的语言标准还提炼了很多基础设施,比如大量使用SFINAE并泛化之,提供enable if, constexpr if, 乃至自动类型推断和concept check,和Java那边的套路是完全不一样的。

    可以说不深入理解泛型技术基本,就不能很好理解现代的C++了。
    2018-01-10
    6
  • edisonhuang
    C++通过范型消除了C语言中很多易出bug的代码,实现代码重用。其中关键在于:算法的泛型;类型的泛型;数据结构(数据容器)的泛型。
    C++通过类,在构造和析构函数中做资源的申请释放,通过引用解决了用指针来取值的问题。通过操作符的重载让算法代码忽略具体类型,可以有统一的表达。通过类似迭代器的范型容器来统一不同数据结构的统一算法表达。
    通过抽象算法中函数的操作,用函数式编程的方式,实现算法的泛型。
    总之,通过不同粒度的抽象,而让代码重用更容易,bug更少,更好维护和扩展
    2019-06-18
    3
  • CH_G318
    有些代码跑不通,总是报错,现在修改成下面的样子了:
    template<class T, class Cond>
    struct counter {
        Cond cond; // 添加一个变量
        size_t operator()(size_t c, T t) {
            return c + (cond(t) ? 1 : 0); // 使用变量进行判断
        }
    };


    template<class Iter, class Cond>
    size_t count_if(Iter begin, Iter end, Cond c) {
        auto op = counter<typename Iter::value_type, Cond>{c}; // 初始化counter结构体
        return reduce(begin, end, size_t(0), op);
    }
    2019-01-24
    3
  • 知知知了
    counter结构体有点问题,调了半天。 如果刚上大学能看到耗子书的文章就好了,看谭浩强学的c和c++真浪费生命,编程还沦为了二流,唉
    2018-06-02
    3
  • 郑杰
    可以讲讲java的类型擦除原理吗
    2018-01-09
    3
  • caohuan
    耗子哥 一步步的抽象过程,让我想到了C#和java都是面向对象语言,都有抽象的说法,比如 类为对象的抽象,接口为 类的抽象,有了抽象的思维,会让实现变得友好,逻辑也清晰,耗子哥的专栏也是这样的设计思想。
    2018-11-07
    2
  • saiyn
    从c到c++的发展过程,让我深刻理解了迭代器是个什么鬼,感谢耗子叔
    2018-05-31
    2
  • 夏洛克的救赎
    如何理解aop
    2018-05-20
    2
  • 上上签
    认真仔细学习,才觉得真是很不错的,不白付费。
    2018-02-14
    2
  • JK.Ryan
    写的很赞👍🏾,感觉也可以顺带讲一下Go的接口,对比多语言可以更加突出“范式”:)

    作者回复: 后面会有的

    2018-01-11
    2
  • Join
    读起来真是太享受了,感觉之前看的那些STL知识被瞬间点燃了,以前思考并未达到这样的深度,能做到将技术和业务逻辑分离开的代码真是太通用了,现在回去再读一遍STL源码解析会更有体会
    2018-01-10
    2
  • 云学
    恰巧不久前实现过迭代器,所以读起来非常享受
    2018-01-09
    2
  • Geek_e5dad7
    看到大家都说看的很享受,但是我真的看不懂😭
    2019-10-22
    1
    1
  • karas
    实在不怎么懂cpp,对标Java说一点。感觉cpp做到通用操作最重要的是操作符重载,比如上面的累加的实现主要就是靠++重载定义next(),*重载定义怎么取对象的值,+重载定义累加的逻辑。对标Java,Java没有操作符重载,他主要依赖接口去规约必要的通用操作。比如一般容器会实现iterator接口,涉及到排序则要求<T extends Comparator>类型参数。凭直觉来讲,操作符可能更加灵活一点。
    另外最后介绍的函数参数,应该算是Java里的匿名类吧,当然j8也可以用lambda了,不过我倒觉得这和泛型无关吧,算是函数式的概念。
    2019-06-07
    1
  • 桃子妈妈
    大神就是把复杂的知识简单化的讲解出来,好厉害
    2019-06-06
    1
  • 不记年
    将泛型做到极致的算法我觉得就是一些方法调用的集合,并且调用的方法完全隐藏类型的实现,也就是说从算法内部完全获得不到传入参数的信息。这些方法调用所体现的语义与算法的名字是等价的。
    2019-06-04
    1
  • escray
    曾经啃过 C++ Prime,也翻过 Thinking in C++,不过一直没有使用 C++ 写过真实的业务实现代码,所以始终处于 C++ 菜鸟的境地。

    从这篇文章中,终于知道 C++ 的出现,并不是简单的增加了所谓“面向对象”的特性,而是在很大程度上采用泛型编程来解决 C 语言在工程实现上面临的一些问题。

    我个人比较偏好 C# 或者 Ruby 一类的语言,相对来说,这两种语言更贴近与业务逻辑,对于底层的依赖不多,但是感觉在某种意义上也实现了“泛型编程”范式,不知道这样理解是否正确。

    另外,对于电影的那则留言,版本三似乎可以是:

    电影(人物1, 人物2, 群演, 情节(A,B)){
      情节(人物1, 人物2, 群演)
    }

    主要区别在于情节是可以通过函数调用传递过来,由拍电影的人决定采用什么样的情节。
    2019-05-30
    1
  • 好久没看到谈编程范式的文章了,回忆起当初看《多范式编程》那本书,还是看本文更有感触
    2018-02-28
    1
收起评论
32
返回
顶部