C++是在 C 语言基础上开发的一种集面向对象编程、泛型编程和过程化编程于一体的编程语言,是C语言的超集。本书是根据2003年的ISO/ANSI C++标准编写的,通过大量短小精悍的程序详细而全面地阐述了 C++的基本概念和技术,并专辟一章介绍了C++11新增的功能。
《C++ Primer Plus(第6版)中文版》分18章,分别介绍了C++程序的运行方式、基本数据类型、复合数据类型、循环和关系表达式、分支语句和逻辑运算符、函数重载和函数模板、内存模型和名称空间、类的设计和使用、多态、虚函数、动态内存分配、继承、代码重用、友元、异常处理技术、string类和标准模板库、输入/输出、C++11新增功能等内容。
《C++ Primer Plus(第6版)中文版》针对C++初学者,从C语言基础知识开始介绍,然后在此基础上详细阐述C++新增的特性,因此不要求读者有C语言方面的背景知识。《C++ Primer Plus(第6版)中文版》可作为高等院校教授C++课程的教材,也可供初学者自学C++时使用。
C++简史
在过去的几十年,计算机技术以令人惊讶的速度发展着,当前,笔记本电脑的计算速度和存储信息的能力超过了 20
世纪
60
年代的大型机。很多程序员可能还记得,将数叠穿孔卡片提交给充斥整个房间的大型计算机系统的时代,而这种系统只有 100KB
的内存,比当今智能手机的内存都少得多。计算机语言也得到了发展,尽管变化可能不是天翻地覆的,但也是非常重要的。体积更大、功能更强的计算机引出了更大、更复杂的程序,而这些程序在程序管理和维护方面带来了新的问题。
在
20
世纪
70
年代,
C
和
Pascal
这样的语言引领人们进入了结构化编程时代,这种机制把秩序和规程带进了迫切需要这种性质的领域中。除了提供结构化编程工具外,C
还能生成简洁、快速运行的程序,并提供了处理硬件问题的能力,如管理通信端口和磁盘驱动器。这些因素使 C
语言成为
20
世纪
80
年代占统治地位的编程语言。同时,20
世纪
80
年代,人们也见证了一种新编程模式的成长:面向对象编程(
OOP
)。
SmallTalk
和
C++
语言具备这种功能。下面更深入地介绍
C
和
OOP
。
1.2.1 C 语言
20
世纪
70
年代早期,贝尔实验室的
Dennis Ritchie
致力于开发
UNIX
操作系统(操作系统是能够管理计算机资源、处理计算机与用户之间交互的一组程序。例如,操作系统将系统提示符显示在屏幕上以提终端式界面、提供管理窗口和鼠标的图形界面以及运行程序)。为完成这项工作,Ritchie
需要一种语言,它必须简洁,能够生成简洁、快速的程序,并能有效地控制硬件。传统上,程序员使用汇编语言来满足这些需求,汇编语言依赖于计算机的内部机器语言。然而,汇编语言是低级(low-level
)语言,即直接操作硬件,如直接访问
CPU
寄存器和内存单元。因此汇编语言针对于特定的计算机处理器,要将汇编程序移植到另一种计算机上,必须使用不同的汇编语言重新编写程序。这有点像每次购买新车时,都发现设计人员改变了控制系统的位置和功能,客户不得不
重新学习驾驶。然而,UNIX
是为在不同的计算机(或平台)上工作而设计的,这意味着它是一种高级语言。高级(high-level
)语言致力于解决问题,而不针对特定的硬件。一种被称为编译器的特殊程序将高级语言翻译成特定计算机的内部语言。这样,就可以通过对每个平台使用不同的编译器来在不同的平台上使用同一个高级语言程序了。Ritchie
希望有一种语言能将低级语言的效率、硬件访问能力和高级语言的通用性、可移植性融合在一起,于是他在旧语言的基础上开发了 C
语言。
1.2.2 C 语言编程原理
由于
C++
在
C
语言的基础上移植了新的编程理念,因此我们首先来看一看
C
所遵循的旧的理念。一般
来说,计算机语言要处理两个概念
—
数据和算法。数据是程序使用和处理的信息,而算法是程序使用的
方法(参见图
1.1
)。
C
语言与当前最主流的语言一样,在最初面世时也是过程性(
procedural
)语言,这意
味着它强调的是编程的算法方面。从概念上说,过程化编程首先要确定计算机应采取的操作,然后使用编
程语言来实现这些操作。程序命令计算机按一系列流程生成特定的结果,就像菜谱指定了厨师做蛋糕时应
遵循的一系列步骤一样。
随着程序规模的扩大,早期的程序语言(如
FORTRAN
和
BASIC
)都会遇到组织方面的问题。例
如,程序经常使用分支语句,根据某种测试的结果,执行一组或另一组指令。很多旧式程序的执行路
径很混乱(被称为“意大利面条式编程”),几乎不可能通过阅读程序来理解它,修改这种程序简直是一场灾难。为了解决这种问题,计算机科学家开发了一种更有序的编程方法—
结构化编程(
structured programming)。
C
语言具有使用这种方法的特性。例如,结构化编程将分支(决定接下来应执行哪个 指令)限制为一小组行为良好的结构。C
语言的词汇表中就包含了这些结构(for
循环、
while 循环、do while
循环和
if else
语句)。
图 1.1 数据+算法=程序
另一个新原则是自顶向下(
top-down
)的设计。在 C
语言中,其理念是将大型程序分解成小型、便于管理的任务。如果其中的一项任务仍然过大,则将它分解为更小的任务。这一过程将一直持续下去,直到将程序划分为小型的、易于编写的模块(整理一下书房。先整理桌子、桌面、档案柜,然后整理书架。好,先从桌子开始,然后整理每个抽屉,从中间的那个抽屉开始整理。 也许我都可以管理这项任务)。C
语言的设计有助于使用这种方法,它鼓励程序员开发程序单元(函 数)来表示各个任务模块。如上所述,结构化编 程技术反映了过程性编程的思想,根据执行的操
作来构思一个程序。
1.2.3 面向对象编程
虽然结构化编程的理念提高了程序的清晰度、可靠性,并使之便于维护,但它在编写大型程序时,仍
面临着挑战。为应付这种挑战,
OOP
提供了一种新方法。与强调算法的过程性编程不同的是,
OOP
强调的
是数据。
OOP
不像过程性编程那样,试图使问题满足语言的过程性方法,而是试图让语言来满足问题的要求。其理念是设计与问题的本质特性相对应的数据格式。在 C++
中,类是一种规范,它描述了这种新型数据格式,对象是根据这种规范构造的特定数据结构。例如,类可以描述公司管理人员的基本特征(姓名、头衔、工资、特长等),而对象则代表特定的管理人员 (Guilford Sheepblat
、副总裁、
$925 000
、知道如何恢复
Windows
注册表)。通常,类规定了可使用哪些数 据来表示对象以及可以对这些数据执行哪些操作。例如,假设正在开发一个能够绘制矩形的计算机绘图程序,则可以定义一个描述矩形的类。定义的数据部分应包括顶点的位置、长和宽、4
条边的颜色和样式、矩形内部的填充颜色和图案等;定义的操作部分可以包括移动、改变大小、旋转、改变颜色和图案、将矩形复制到另一个位置上等操作。这样,当使用该程序来绘制矩形时,它将根据类定义创建一个对象。该对象保存了描述矩形的所有数据值,因此可以使用类方法来修改该矩形。如果绘制两个矩形,程序将创建两个对象,每个矩形对应一个。OOP 程序设计方法首先设计类,它们准确地表示了程序要处理的东西。例如,绘图程序可能定义表示矩形、直线、圆、画刷、画笔的类。类定义描述了对每个类可执行的操作,如移动圆或旋转直线。然后您便可以设计一个使用这些类的对象的程序。从低级组织(如类)到高级组织(如程序)的处理过程叫做自
下向上(
bottom-up
)的编程。 OOP 编程并不仅仅是将数据和方法合并为类定义。例如,
OOP
还有助于创建可重用的代码,这将减少 大量的工作。信息隐藏可以保护数据,使其免遭不适当的访问。
多态让您能够为运算符和函数创建多个定 义,通过编程上下文来确定使用哪个定义。继承让您能够使用旧类派生出新类。正如接下来将看到的那样,OOP 引入了很多新的理念,使用的编程方法不同于过程性编程。它不是将重点放在任务上,而是放在表示概念上。有时不一定使用自上向下的编程方法,而是使用自下向上的编程方法。本书将通过大量易于掌握的示例帮助读者理解这些要点。设计有用、可靠的类是一项艰巨的任务,幸运的是,OOP
语言使程序员在编程中能够轻松地使用已有的类。厂商提供了大量有用的类库,包括设计用于简化 Windows
或
Macintosh
环境下编程的类库。真
正的优点之一是:可以方便地重用和修改现有的、经过仔细测试的代码。
1.2.4 C++和泛型编程
泛型编程(
generic programming
)是
C++
支持的另一种编程模式。它与
OOP
的目标相同,即使重用代码和抽象通用概念的技术更简单。不过 OOP
强调的是编程的数据方面,而泛型编程强调的是独立于特定数据类型。它们的侧重点不同。OOP
是一个管理大型项目的工具,而泛型编程提供了执行常见任务(如对数据排序或合并链表)的工具。术语泛型(generic
)指的是创建独立于类型的代码。
C++
的数据表示有多种类型—
整数、小数、字符、字符串、用户定义的、由多种类型组成的复合结构。例如,要对不同类型的数据进行排序,通常必须为每种类型创建一个排序函数。泛型编程需要对语言进行扩展,以便可以只编写一个泛型(即不是特定类型的)函数,并将其用于各种实际类型。C++
模板提供了完成这种任务的机制。
1.2.5 C++的起源
与
C
语言一样,
C++
也是在贝尔实验室诞生的,
Bjarne Stroustrup
于
20
世纪
80
年代在这里开发
出了这种语言。用他自己的话来说,“
C++
主要是为了我的朋友和我不必再使用汇编语言、
C
语言或其他现代高级语言来编程而设计的。它的主要功能是可以更方便地编写出好程序,让每个程序员更加快乐”。
Bjarne Stroustrup
的主页
Bjarne Stroustrup
设计并实现了
C++
编程语言,他是权威参考手册《
The C++ Programming Language
》
和《
The design and Evolution of C++
》的作者。读者应将他位于
AT&T Labs Research
上的个人网站作为首
选的
C++
书签:
http
:
//www.research.att.com/-bs/
该网站包括了
C++
语言有趣的发展历史、
Bjarne
的传记材料和
C++ FAQ
。
Bjarne
被问得最多的问题 是:Bjarne Stroustrup
应该如何读。您可以访问
Stroustrup
的网站,阅读
FAQ
部分并下载
.WAV
文件,亲 自听一听。
Stroustrup
比较关心的是让
C++
更有用,而不是实施特定的编程原理或风格。在确定
C++
语言特性方面,真正的编程需要比纯粹的原理更重要。Stroupstrup
之所以在
C
的基础上创建
C++
,是因为
C
语言简洁、适合系统编程、使用广泛且与 UNIX
操作系统联系紧密。
C++
的
OOP
方面是受到了计算机模拟语言
Simula67
的启发。Stroustrup
加入了
OOP
特性和对
C
的泛型编程支持,但并没有对
C
的组件作很大的改动。因此,
C++是 C
语言的超集,这意味着任何有效的
C
程序都是有效的
C++
程序。它们之间有些细微的差异,但无足轻重。C++程序可以使用已有的
C
软件库。库是编程模块的集合,可以从程序中调用它们。库对很多常见的编程问题提供了可靠的解决方法,因此能节省程序员大量的时间和工作量。这也有助于 C++
的广泛传播。名称 C++
来自
C
语言中的递增运算符
++
,该运算符将变量加
1
。名称
C++
表明,它是
C
的扩充版本。
计算机程序将实际问题转换为计算机能够执行的一系列操作。
OOP
部分赋予了
C++
语言将问题所
涉及的概念联系起来的能力,
C
部分则赋予了
C++
语言紧密联系硬件的能力(参见图
1.2
),这种能力上的结合成就了 C++
的广泛传播。从程序的一个方面转到另一个方面时,思维方式也要跟着转换(确实,有些 OOP
正统派把为
C
添加
OOP
特性看作是为猪插上翅膀,虽然这是头瘦骨嶙峋、非常能干的猪)。另外,C++
是在
C
语言的基础上添加
OOP
特性,您可以忽略
C++
的面向对象特性,但将错过很多有用的东西。 在 C++
获得一定程度的成功后,
Stroustrup
才添加了模板,这使得进行泛型编程成为可能。在模板特性
被使用和改进后,人们才逐渐认识到,它们和
OOP
同样重要
—
甚至比
OOP
还重要,但有些人
这么认为。C++
融合了
OOP
、泛型编程和传统的过程性方法,这表明
C++
强调的是实用价值,而不是意识形态方 法,这也是该语言获得成功的原因之一。