作为结构化的面向过程的编程语言,C已经是非常优秀的了,它简单、高效、灵活、功能强大。但是,随着软件开发的规模越来越大,所针对的问题和系统越来越复杂,对软件维护和重用的需求越来越高。仅仅靠面向过程的编程技术,就显得有点力不从心了。因此,针对问题的面向对象编程技术,就应运而生。
1985年,Bjarne Stroustrup对C语言进行了扩充,在保留C语言优点的基础上,添加了面向对象的特征和功能后,开发出了C++语言。1994年,Alexander Stepanov又将泛型编程技术引入C++。使得现在的C++,成为了一种同时具有面向过程、面向对象和泛型编程的特征,功能强大、运行高效、使用广泛的混合型程序设计语言。
1998年,C++最终成为国际标准(ISO/IEC 14882:1998 Programming languages -- C++,程序设计语言——C++)。2003年,ISO又推出了它的第2版(ISO/IEC 14882:2003),对第1版中的错误进行了修订。
1)OOP
程序设计语言,在思想上发展很快,在技术上也是不断创新。经历了手工操作(控制面板)、机器语言、汇编语言、宏汇编语言、高级语言和第4代语言等多个阶段。
OOP(Object-Oriented Programming面向对象编程)只是在高级程序设计语言中,流行的多种编程技术之一。
(1)软件重用
在现代高级语言中,使用了有多种不同的编程思想和软件技术。在强调软件重用的今天,为了减轻编程强度,避免重复劳动,存在着多种重用的方法和思路。主要有:
<!--[if !supportLists]-->l <!--[endif]-->面向对象(OO = Object-Oriented)——针对问题的面向对象的技术,通过类的继承和对象的多态来实现对象的重用;
<!--[if !supportLists]-->l <!--[endif]-->泛型编程(generic programming)——面向算法的泛型编程技术,则通过模版、容器和迭代器等来实现源代码块的重用;
<!--[if !supportLists]-->l <!--[endif]-->组件编程(components programming)——面向方案和分布式计算的组件编程技术,通过功能封装和接口标准化,实现了软件模块的组合和共享;
<!--[if !supportLists]-->l <!--[endif]-->面向方面(AO = Aspect-Oriented)——最新的面向方面的编程,则利用不同问题所具有的共同特性,从某个方面出发,着眼于关注点,开发出具有多量化(适用于多个问题中)和不知觉性(对程序员透明)的程序,也达到了代码共享和模块重用的目的。
当然,面向过程(procedure-oriented)和算法的结构化程序设计,是所有软件开发的底层基础。结构化的面向过程的编程,采用自顶向下的方法,对问题进行逐级分解。将常用的代码模块写成函数和子过程,通过函数和子过程的调用,同样做达到了目标代码块的重用。
<!--[if !vml]--><!--[endif]-->
(2)面向对象
面向对象编程的三个基本特征是:
<!--[if !supportLists]-->l <!--[endif]-->封装(encapsulation)—— 是对问题的抽象,以达到信息隐藏的目的。通过类和对象,将属性(数据/变量)和方法(操作/函数)封装在一个黑箱内,将细节隐藏起来。既可以保护数据不被他人恶意或大意地修改,又能防止其他程序员编写高耦合度的代码,还方便了今后对对象内部的修改和升级;
<!--[if !supportLists]-->l <!--[endif]-->继承(inheritance)—— 利用问题和事物的相似性,通过类的(多层)继承机制,可以达到减少软件开发难度和重用已有对象的属性和方法之目的;
<!--[if !supportLists]-->l <!--[endif]-->多态(polymorphism)—— 同一操作或响应,可以同时针对多个可选的类型和对象,并且能够自动在它们中间选择最合适的来进行。多态可以分为:
<!--[if !supportLists]-->n <!--[endif]-->编译时多态:包括函数和运算符的重载(overload),通过早期的静态绑定(binding)来实现;
<!--[if !supportLists]-->n <!--[endif]-->运行时多态:通过继承结合晚期动态绑定来实现——用同一基类的指针,可以访问各个不同派生类中的同名方法和函数。
(3)基本概念
面向对象的基本概念:(类似的概念多、表达不够准确、各处的用法各异)
<!--[if !supportLists]-->l <!--[endif]-->抽象(abstraction)—— 一个问题的本质特征。忽略一个对象的细节,致力于一般的合适级别的程序能力。抽象是在事物的周围绘制透明的盒子,是定义事物接口的行为
<!--[if !supportLists]-->l <!--[endif]-->信息隐藏(information hiding)—— 限制外部对类属性(数据成员)的访问
<!--[if !supportLists]-->l <!--[endif]-->封装(encapsulation)—— 将某种保密和隐匿应用到类中的数据和一些方法(函数或子例程)上。封装确保一个对象只能通过确定的渠道(即类的公用方法)才可被修改。封装意味着将数据及相关函数打包到一个单一的单元(类)中。每个对象暴露一个接口(公用方法),规定其他对象可以如何读取或修改它
<!--[if !supportLists]-->l <!--[endif]-->类(class)—— 问题的抽象,对象的模版,接口的实现。例如int是整数的模版、CPoint是点的模版
<!--[if !supportLists]-->l <!--[endif]-->对象(object)—— 问题中的事物,类的实例(变量),拥有数据和功能。若int i; CPoint p; 则i是int的实例变量,p是CPoint的实例对象
<!--[if !supportLists]-->l <!--[endif]-->实例(instance)—— 一个对象,是某个类的示例
<!--[if !supportLists]-->l <!--[endif]-->实例化(intantiate)—— 由类定义创建对象
<!--[if !supportLists]-->l <!--[endif]-->继承(inheritance)—— 创建子类的机制,一种“is a”或“is like”关系,形成类层次结构。是OOP中对象重用的核心概念
<!--[if !supportLists]-->l <!--[endif]-->子类(subclass)—— 继承自另一个类的派生类(derived class)
<!--[if !supportLists]-->l <!--[endif]-->超类(superclass父类)—— 被另一个类继承的基类(base class)
<!--[if !supportLists]-->l <!--[endif]-->虚函数(virtual function)—— 可以在子类中被覆盖(override)的函数
<!--[if !supportLists]-->l <!--[endif]-->纯虚函数(pure virtual function)—— 只有声明没有定义的函数,必须在派生类中被覆盖
<!--[if !supportLists]-->l <!--[endif]-->抽象类(abstract class)—— 至少包含一个纯虚函数的类,不能被实例化
<!--[if !supportLists]-->l <!--[endif]-->具体类(concrete class)—— 可以实例化的类,不包含纯虚函数
<!--[if !supportLists]-->l <!--[endif]-->接口(interface)—— 纯抽象的类,类的模版。接口中的所有的方法(成员函数)都只有声明,没有定义(都是纯虚函数)。必须在接口的派生类中,实现接口的全部方法。接口可以看成是一个,定义了一套内部行为的,若干操作特征标记的集合。(在C++中,也把类的公用成员函数叫做接口)
<!--[if !supportLists]-->l <!--[endif]-->属性(attribute)—— 类和接口中的数据信息,又叫数据成员(data member)或成员变量(member variable)。属性是类知道的事物
<!--[if !supportLists]-->l <!--[endif]-->方法(method)—— 类操作的实现,又叫成员函数(member function)。方法是类要做的事情。(在C++中,也把虚函数叫做方法)
<!--[if !supportLists]-->l <!--[endif]-->重载(overload)—— 一个类中的,参数的数目、类型或排列顺序不同的多个同名方法(成员函数)
<!--[if !supportLists]-->l <!--[endif]-->覆盖(override)—— 在子类中重新定义(与父类中的定义有区别的)属性和方法
<!--[if !supportLists]-->l <!--[endif]-->持久化(persistence)—— 将对象存入永久存储中(如文件、数据库等)
<!--[if !supportLists]-->l <!--[endif]-->持久对象(persistent object)—— 存入永久存储的对象
(4)简史
计算机科学中,对象的概念和实例,最早出现在MIT的PDP-1中(1960年)。1963年Ivan Sutherland在其博士论文中所编写的计算机程序Sketchpad,应用了对象技术。
但是,作为一种程序设计方法,OOP(Object-Oriented Programming面向对象编程)最早出现在1967年,由(位于挪威首都奥斯陆的)挪威计算中心的Ole-Johan Dahl和Kristen Nygaard,在他们发明的Simula67语言中首先引入的。Simula语言是在Algol60基础上,加入了对象、类和继承等概念后开发出来的,它在OOP的历史中占有重要地位。
Smalltalk是1970年代,由美国施乐(Xerox)公司PARC(Palo Alto Research Center帕洛阿尔托研究中心)的Alan Kay、Dan Ingalls、Ted Kaehler和Adele Goldberg等人,开发的一种面向对象和动态类型的交互式程序设计语言。它受到了Sketchpad和Simula的影响,但是Smalltalk被设计成一个全动态系统的纯OOP,程序的所有成分都是对象(为了提高运行效率,C++/Java/C# 中的基本数据类型都不是对象),对象可以被动态地创建、修改和销毁。在Smalltalk中还创造出词汇“'inheritance(继承)”和“Object-oriented programming(面向对象的程序设计)”。
使OOP走向辉煌的是1985年发明的C++,随着GUI(Graphical User Interfaces图形用户界面)的流行,C++的地位更加巩固。
但是,因特网的发展和万维网的流行,又催生了另一个重要的OOP语言——Java(1995年)。为了与Sun公司的Java竞争,微软公司也推出了一种OOP语言——C#(2000)。
2)C++的历史与发展
(1)历史
1979年,贝尔实验室的计算机科学家,丹麦人Bjarne Stroustrup(http://public.research.att.com/~bs/homepage.html)在Simula 67的启发下,将C语言扩展为带类的C (C with Classes),1983年Rick Mascitti将其命名为C++。
1985年10月Bjarne Stroustrup实现了C++的第一个商用版本,与此同时他还出版了《The C++ Programming Language(C++程序设计语言)》的第1版,成为C++的事实标准。C++的第1版,提供了面向对象程序设计的基本特征:类和对象、单继承、虚函数、公有/私有成员的访问控制、函数重载等。
1989年推出C++的第2版,增加了多继承、抽象类、静态和常型成员函数、保护成员的访问控制、运算符重载等新特性,促使C++语言流行起来。1990年1月1日Margaret A. Ellis和Bjarne Stroustrup出版了《The Annotated C++ Reference Manual(带注释的C++参考手册)》。1991年Bjarne Stroustrup推出了《C++程序设计语言》的第2版:The C++ Programming Language (2nd edition)。
1993年推出C++的第3版,增加了模板、异常处理和嵌套类等新特性.1994年3月29日Bjarne Stroustrup出版了《The Design and Evolution of C++(C++的设计和演化)》。1997年Bjarne Stroustrup推出了《C++程序设计语言》的第3版:The C++ Programming Language (3rd edition)。
1994年7月,ANSI/ISO C++标准委员会,通过了Alexander Stepanov提出的STL(Standard Template Library标准模板库)方案。
1998年9月1日C++成为国际标准(ISO/IEC 14882:1998 Programming languages -- C++,程序设计语言——C++),添加的新特性主要有:命名空间、新的强制类型转换、布尔类型和STL。2000年2月15日Bjarne Stroustrup又推出了《C++程序设计语言》的特别版:The C++ Programming Language (Special Edition)。
2003年10月15日ISO推出了C++标准的第2版ISO/IEC 14882:2003,该版本在语法特征上没有什么变化,只是纠正了原版的各种错误,并进行了一些技术上的修订。
(2)发展
下面分别介绍标准C++的下一个版本的概要,以及从C++派生的Java和C# 语言。
<!--[if !supportLists]-->l <!--[endif]-->C++0x
C++0x是ISO计划于2009年完成的下一版C++语言。
指导原则:
<!--[if !supportLists]-->n <!--[endif]-->C++是一种倾向系统编程的通用程序设计语言:
<!--[if !supportLists]-->u <!--[endif]-->是更好的C
<!--[if !supportLists]-->u <!--[endif]-->支持数据抽象
<!--[if !supportLists]-->u <!--[endif]-->支持面向对象的编程
<!--[if !supportLists]-->u <!--[endif]-->支持泛型编程
系统编程是指,传统上与操作系统和基础工具有关的任务。包括:操作系统内核、设备驱动程序、系统工具、网络、字处理工具、编译器、某些种类的图形学和GUI、数据库系统、游戏引擎、CAD/CAM、电信系统等等。这类工作很好地代表了当前的C++用户。
<!--[if !supportLists]-->n <!--[endif]-->C++0x的目标是保持上面这些特征不变。删除这些风范(paradigms)(例如,使C++与C的兼容性减少)或添加激进的新风范,都不是它的目标。我们的目标是可以最有效地使用这些技术之联合的程序设计风格,是改善作为多风范程序设计语言的C++。
<!--[if !supportLists]-->n <!--[endif]-->C++0x语言部分的高级目标是:
<!--[if !supportLists]-->u <!--[endif]-->使C++成为一种更好的系统编程和库创建的语言,而不是为特定应用提供专门的功能(例如,数值计算或窗口风格的应用程序开发)
<!--[if !supportLists]-->u <!--[endif]-->通过增加一致性、更强的保证和支持初学者的工具,使C++更容易教授和学习
换句话说,C++0x应该比C++98更好,可能在更多的一些领域比C++98更通用。当它去支持专门的应用领域,诸如数值计算、窗口风格的应用程序开发和嵌入式系统编程时,C++0x将会依靠库。
有效的基本语言特征(例如栈分配对象和指针)加上通用灵活的抽象机制(例如类和模板),使得库的使用在不可思议的广泛应用领域中充满了吸引力,减少了对新语言特性的需求。
我们不能够为了使语言易教易学而删除它特性,稳定性和兼容性是主要的关注点。所以,使规则通用化和添加容易使用的特性,是我们可做的选择。后者做起来会更容易一些,例如更好的库工具,诸如容器和算法,可以节约用户解决与低级设施(如数组和指针)相关问题的时间。因此,简化库的定义和使用的语言工具,将会为C++0x更容易使用作出贡献。
<!--[if !supportLists]-->n <!--[endif]-->对C++0x改进,应该使所得到的结果语言更容易学习和使用。重点规则是:
<!--[if !supportLists]-->u <!--[endif]-->提供稳定性和(与C++98,以及,如果可能,与C的)兼容性
<!--[if !supportLists]-->u <!--[endif]-->更喜欢标准库而不是语言扩展
<!--[if !supportLists]-->u <!--[endif]-->只做可以改变人们思维方式的改变
<!--[if !supportLists]-->u <!--[endif]-->更喜欢通用化而不是专门化
<!--[if !supportLists]-->u <!--[endif]-->同时支持专家和初学者
<!--[if !supportLists]-->u <!--[endif]-->增加类型的安全性(通过提供安全的备选方案来代替当前的非安全工具)
<!--[if !supportLists]-->u <!--[endif]-->改进直接操作硬件的性能和能力
<!--[if !supportLists]-->u <!--[endif]-->适应真实世界(C++的目标不是创建最优美的语言,而是提供最有用的语言)
语言特征
<!--[if !supportLists]-->n <!--[endif]-->用using定义模板的别名
<!--[if !supportLists]-->n <!--[endif]-->模板中的>后的空格是可选的
<!--[if !supportLists]-->n <!--[endif]-->可以用常数列表来为容器赋初值(C++98只能对数组和传统结构赋)
<!--[if !supportLists]-->n <!--[endif]-->可以省去迭代器前的类型说明
template<class T> using Vec = vector<T,My_alloc<T>>;
Vec<double> v = { 2.3, 1.2, 6.7, 4.5 };
sort(v);
for(auto p = v.begin(); p!=v.end(); ++p)
cout << *p << endl;
<!--[if !supportLists]-->n <!--[endif]-->C++0x中,最重大的扩展建议是,引入“概念(concept)”(如Container)—— 类型的类型,它指定类型所需的特性(properties)(如where)。有了概念,我们可以进行更有意义的类型检查、提供更好的错误信息和更强大的表达能力。它还可以从当前的容器、迭代器和算法出发,导出更好的库接口。
注:这里的概念与C# 和Java中的元数据有点类似。
template<Container C> // sort container using <
void sort(C& c);
template<Container C, Predicate Cmp> // sort container using Cmp
where Can_call_with<Cmp,typename C::value_type>
void sort(C& c, Cmp less);
template<Random_access_iterator Ran> // sort sequence using <
void sort(Ran first, Ran last);
template<Random_access_iterator Ran, Predicate Cmp> // sort sequence using Cmp
where Can_call_with<Cmp,typename Ran::value_type>
void sort(Ran first, Ran last, Cmp less);
库程序(Library Facilities)
<!--[if !supportLists]-->n <!--[endif]-->对程序员直接有用几个库功能
<!--[if !supportLists]-->u <!--[endif]-->Hash表
<!--[if !supportLists]-->u <!--[endif]-->正则表达式
<!--[if !supportLists]-->u <!--[endif]-->通用灵巧指针
<!--[if !supportLists]-->u <!--[endif]-->可扩展的随机数程序
<!--[if !supportLists]-->u <!--[endif]-->数学特殊函数
<!--[if !supportLists]-->n <!--[endif]-->在STL之上创建泛型库的扩展功能:
<!--[if !supportLists]-->u <!--[endif]-->多态函数对象包装
<!--[if !supportLists]-->u <!--[endif]-->元组(tuple)类型
<!--[if !supportLists]-->u <!--[endif]-->类型特性(traits)
<!--[if !supportLists]-->u <!--[endif]-->增强型成员指针适配器(adaptor)
<!--[if !supportLists]-->u <!--[endif]-->计算函数对象返回类型的统一方法
<!--[if !supportLists]-->u <!--[endif]-->增强型联编器