C
- C 语言是一个静态弱类型语言,在使用变量时需要声明变量类型,但是类型间可以有隐式转换;
- 不同的变量类型可以用结构体(struct)组合在一起,以此来声明新的数据类型;
- C 语言可以用 typedef 关键字来定义类型的别名,以此来达到变量类型的抽象;
- C 语言是一个有结构化程序设计、具有变量作用域以及递归功能的过程式语言;
- C 语言传递参数一般是以值传递,也可以传递指针;
- 通过指针,C 语言可以容易地对内存进行低级控制,然而这加大了编程复杂度;
- 编译预处理让 C 语言的编译更具有弹性,比如跨平台。
优点
- 相信程序员;
- 不会阻止程序员做任何底层的事;
- 保持语言的最小和最简的特性;
- 保证 C 语言的最快的运行速度,那怕牺牲移值性。
C++
- 用引用来解决指针的问题。
- 用 namespace 来解决名字空间冲突的问题。
- 通过 try-catch 来解决检查返回值编程的问题。
- 用 class 来解决对象的创建、复制、销毁的问题,从而可以达到在结构体嵌套时可以深度复制的内存安全问题。
- 通过重载操作符来达到操作上的泛型。
- 通过模板 template 和虚函数的多态以及运行时识别来达到更高层次的泛型和多态。
- 用 RAII、智能指针的方式,解决了 C 语言中因为需要释放资源而出现的那些非常 ugly 也很容易出错的代码的问题。
- 用 STL 解决了 C 语言中算法和数据结构的 N 多种坑。
C++ 泛型(泛型的本质)
- 通过类中的构造、析构、拷贝构造,重载赋值操作符,标准化(隐藏)了类型的内存分配、释放和复制的操作。
- 通过重载操作符,可以标准化类型的比较等操作。
- 通过 iostream,标准化了类型的输入、输出控制。
- 通过模板技术(包括模板的特化),来为不同的类型生成类型专属的代码。
- 通过迭代器来标准化数据容器的遍历操作。
- 通过面向对象的接口依赖(虚函数技术),来标准化了特定类型在特定算法上的操作。
- 通过函数式(函数对象),来标准化对于不同类型的特定操作。
函数式编程(以 Stateless(无状态)和 Immutable(不可变)为主要特点)
- first class function(头等函数):这个技术可以让你的函数就像变量一样来使用。也就是说,你的函数可以像变量一样被创建、修改,并当成变量一样传递、返回,或是在函数中嵌套函数。
- tail recursion optimization(尾递归优化) : 我们知道递归的害处,那就是如果递归很深的话,stack 受不了,并会导致性能大幅度下降。因此,我们使用尾递归优化技术——每次递归时都会重用 stack,这样能够提升性能。当然,这需要语言或编译器的支持。Python 就不支持。
- map & reduce:这个技术不用多说了,函数式编程最常见的技术就是对一个集合做 Map 和 Reduce 操作。这比起过程式的语言来说,在代码上要更容易阅读。(传统过程式的语言需要使用 for/while 循环,然后在各种变量中把数据倒过来倒过去的)这个很像 C++ STL 中 foreach、find_if、count_if 等函数的玩法。
- pipeline(管道):这个技术的意思是,将函数实例成一个一个的 action,然后将一组 action 放到一个数组或是列表中,再把数据传给这个 action list,数据就像一个 pipeline 一样顺序地被各个函数所操作,最终得到我们想要的结果。
- recursing(递归) :递归最大的好处就简化代码,它可以把一个复杂的问题用很简单的代码描述出来。注意:递归的精髓是描述问题,而这正是函数式编程的精髓。
- currying(柯里化) :将一个函数的多个参数分解成多个函数, 然后将函数多层封装起来,每层函数都返回一个函数去接收下一个参数,这可以简化函数的多个参数。在 C++ 中,这很像 STL 中的 bind1st 或是 bind2nd。
- higher order function(高阶函数):所谓高阶函数就是函数当参数,把传入的函数做一个封装,然后返回这个封装函数。现象上就是函数传进传出,就像面向对象对象满天飞一样。这个技术用来做 Decorator 很不错。
面向对象的优缺点
优点
- 能和真实的世界交相辉映,符合人的直觉。
- 面向对象和数据库模型设计类型,更多地关注对象间的模型设计。
- 强调于“名词”而不是“动词”,更多地关注对象和对象间的接口。
- 根据业务的特征形成一个个高内聚的对象,有效地分离了抽象和具体实现,增强了可重用性和可扩展性。
- 拥有大量非常优秀的设计原则和设计模式。
- S.O.L.I.D(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转,是面向对象设计的五个基本原则)、IoC/DIP……
缺点
- 代码都需要附着在一个类上,从一侧面上说,其鼓励了类型。
- 代码需要通过对象来达到抽象的效果,导致了相当厚重的“代码粘合层”。
- 因为太多的封装以及对状态的鼓励,导致了大量不透明并在并发下出现很多问题。
基于原型(Prototype)的编程与传统的面对象编程的比较
- 在基于类的编程当中,对象总共有两种类型。类定义了对象的基本布局和函数特性,而接口是“可以使用的”对象,它基于特定类的样式。在此模型中,类表现为行为和结构的集合,对所有接口来说这些类的行为和结构都是相同的。因而,区分规则首先是基于行为和结构,而后才是状态。
- 基于类的语言提倡使用一个关注分类和类之间关系的开发模型。与此相对,原型编程看起来提倡程序员关注一系列对象实例的行为,而之后才关心如何将这些对象划分到最近的使用方式相似的原型对象,而不是分成类。
- 在基于类的语言中,一个新的实例通过类构造器和构造器可选的参数来构造,结果实例由类选定的行为和布局创建模型。
- 在基于原型的系统中构造对象有两种方法,通过复制已有的对象或者通过扩展空对象创建。很多基于原型的系统提倡运行时进行原型的修改,而基于类的面向对象系统只有动态语言允许类在运行时被修改
声明式、命令式、逻辑的、函数式、面向对象的、面向过程的。