C++在C语言的基础上大大增强了面向对象的特性,功能十分强大,目前已经成为软件开发语言的首选。\r\n 本书针对有经验的C语言程序员,采用别具一格的方法和清晰的思路,讲述如何从C过渡到C++。作者紧扣C++语言的核心部分,包括C++必备的特性,以及C++之所以如此强大的其他功能。\r\n 本书是独立于开发平台的,涵盖了各种平台上的C++编译器共有的特性,包括Windows NT,Windows 9x,DOS,UNIX,Macintosh。读者掌握了书中讲述的核心内容之后,可以使用任何一种编译器,在实践中熟悉C++语言的要素。一旦理解了这些要素,阅读C++语言参考手册、图形化用户界面编程手册和特定程序库的文档就会轻车熟路。\r\n 本书还包含许多选读部分,可以帮助读者了解书中没有详述的所有高级主题的概况。\r\n\r\n
第一章 含类的面向对象程序设计\r\n\r\n面向对象程序设计\r\n类\r\n\r\n第二章 不含类的C++\r\n\r\n起始三步曲\r\n函数的变化\r\n严格的类型规则\r\n全局变量的动态初始化\r\n一些列表\r\n\r\n第三章 成员函数产生的抽象性\r\n\r\n抽象性\r\n使用结构\r\n使用具有接口函数的结构\r\n使用具有成员函数的类\r\n\r\n第四章 存取说明符产生的封装性\r\n\r\n存取说明符\r\n类成员可以具有任何存取级别\r\n无限制的存取说明符\r\n专有性并非意味着不可见性\r\n友员类\r\n\r\n第五章 合并和派生产生的层次性\r\n\r\n合并\r\n派生\r\n串联\r\n\r\n第六章 构造函数和析构函数产生的更好的抽象性\r\n\r\n缺省构造函数\r\n析构函数\r\n内建类型\r\n层次和串联\r\n隐式的缺省构造函数和析构函数\r\n串联的另一面\r\n显式调用\r\n控制流\r\n调用时机\r\n\r\n第七章 new函数和delete函数产生的更好的抽象性\r\n\r\n动态对象\r\n动态数组\r\n混合性分配符\r\nrealloc()\r\n内存溢出\r\n\r\n第八章 引用\r\n\r\n形式参数和实际参数\r\n在C和C++中传递量值\r\n在C++中传递引用\r\n引用和指针\r\n在C++中返回引用\r\n重载:引用和量值\r\n联编问题\r\n\r\n第九章 由其他特殊成员函数产生的更好的抽象性\r\n\r\n赋值运算符\r\n拷贝构造函数\r\n输出对象\r\n总结\r\n\r\n第十章 一个示例类\r\n\r\n使用一个int型数\r\n使用一个静态数组\r\n使用一个动态数组\r\n使用一个具有引用计数器的字符串\r\n拷贝构造函数测试\r\n总结表\r\n\r\n第十一章 模板产生的更好的层次性\r\n\r\n定义一个模板\r\n使用模板来定义一个对象\r\n小心对待模板展开\r\n修改容器类的元素\r\n\r\n第十二章 虚函数产生的多态性\r\n\r\nC中的多态性\r\n虚函数\r\nC++中的多态性\r\n有关虚函数的更多内容\r\n\r\n第十三章 进一步了解多态性\r\n\r\n抽象类\r\n派生的选择\r\n虚函数的选择\r\n从构造函数和析构函数中调用虚函数\r\n集中到一个数组中\r\n陷阶\r\n\r\n第十四章 实现一个面向对象的设计\r\n\r\n实现表\r\n例子\r\nIs-A和Has-A\r\n防御性的实现\r\n\r\n第十五章 一个示例程序\r\n\r\nString类\r\nRule、CwRule和HwRule类\r\nScanner类\r\n使用这个程序\r\n示例代码\r\n\r\n第十六章 下一步要学习什么\r\n\r\nconst\r\ninline\r\n带参数的构造函数\r\n成员初始化列表\r\n有效的拷贝构造函数\r\n特殊成员函数\r\n\r\n附录一 C++运算符\r\n附录二 使用量值返回时产生的一个问题\r\n\r\n参考书目\r\n词汇表
本书是为那些想要学习C++的C程序员编写的. 为什么要写结C程序员, 又为什么要写C++呢?我们之所以假定你是一个C程序员, 是因为要学习C++就必须以大量的C语言为基础. 而且目前已经存在很多很好的C语言初级读本, 我们没有任何理由再写一本出来. 但是有关C++的好书却还远远不够. 总之, 这不是一本为初学者写的书. 我们在以下的两节中解释了我们所认为的现有C++书的不足之处以及本书的优点所在. 首先, 我们要谈一下什么是C++.
什么是C++?
C++本质上是带面向对象程序设计(Object—Oriented Programming, OOP)扩展的C语言. 有人可能会说, 某些扩展并非真正是为OOP而进行的. 但是它们中的大多数确实是. C++差不多是C的超集, 但也有一些改变. 我们在第二章“不合类的C++”中将介绍这些改变.
C++的一个重要特征就是它仍然在改变, 所以目前并不存在标准的C++. ANSI和ISO委员会正致力于编写——个标准版本, 现在你所能得到的只是最接近标准版本的C++. 它是ANSI/ISO最新提议的标准版, 而且目前仍然在变动中. 但这并不妨碍几个大的软件生产商销售C++编译器, 而反对数以万计的C++程序员也毫无影响. 编译器的生产商在加入了某些特性提议的标准版本时, 就会将之实现.
这种持续变动的状态是否意味着, ANSI/ISO委员会可能会作出巨大的变动, 从而使你的所有代码作废呢?全世界商业性开发的C++代码可能有上亿行. 有两个原因使得标准化的结果不可能大大地改变原有的方向:一个是决定标准的委员会成员对那些代码中的大多数存在一种既定的兴趣:另一个是即使标准突然改变也仍会支持现有的程序. 因此, 无论这种语言是否被称为C++, 对编译器销售商来说继续支持那些程序都是有市场的.
不断变动的标准意味着你需要做两件事:一是要注意你使用的特性, 这能使你的代码具有可移植性. 在最新提议标准中的特性被所有大的编译器生产商实现之前要慎用它, 二是要时刻准备着随语言的变化而改变. 1989年所写的优秀的C++程序在今天看来并不一定很好, 而且——些在1989年看来很棘手的问题今天或许已有 了更好的解决方案.
虽然将来几乎不会再出现对语言自身的较大补充, 但是重大的修改仍在不断进行. 对C++库的标准化可能是其中之一. 共享的C++使用经验正在增长, 这可能也是一个. 后者比你起初想像的要重要得多. 如果回头看一些早期的c代码, 你会为这些代码是如此的拖沓而感到震惊. 经年累月积累下的开发. 维护和使用C代码的经验教会了我们如何绕过不明之处, C++将经历同样的演化过程. 总而言之, 要时刻注意着那些变化, 否则你将变成一个老古董.
为什么又出一本关于C++的书?
现有c++书的问题在于, 它们像c++语言一样对于初学者比较难. 它们像是一份复杂事物的提纲, 覆盖了一切但却没有重点. 我们相信C++已超越了一本书的复杂度界限, 这是我们的说法, 意思是C++这门语言太复杂了, 是一本书所无法涵盖的. 我们将学习C++和学习物理作比较. 没有人在介绍物理的书中就写入广义 相对论, 即使有也不过是泛泛之谈, 相反学生首先学习牛顿物理学, 逐渐掌握它之后进入到狭义相对论的学习, 对狭义相对论了解之后再进行广义相对论的学习.
c++是非常复杂的, 所以我们提倡也按照上面介绍的方法学习它. C++各个特性的复杂度之和并没有那么大, 问题在于当你将这些特性放在一起时, 它们就会不自觉地相互作用. 我们可以从Bjarne Stroustrup所写的《C++的设计和发展》一书中第330页上的内容来理解这一点. 这位C++的设计者写道:“我想是Martin 0Riordan首次使我注意到这一现象(多个继承和类型转换之间强烈的相互作用). ”请想一下, 这位C++语言的创造者, 一个花了15年来刻苦钻研每一个细节的老手, 还要别人为他指出这些细微的相互作用. Bjarne StroustruP为达到C++的设计目标作了大量非凡的工作, 他将现实世界中非常难的因素都添加了进来, 诸如效率因素. 和C以及现有的链接程序的兼容性. 允许使用多种的设计风格等.
但是要达到这一目标就必须作出某些牺牲, 对C++的初学者来说, 不串的是, 避免发生强烈相互作用的因素被牺牲掉了. 我们所能见到的C++书通常分为两类. 一类是讨论完整C++语言全部特性的, 但是并不深入到这些特性的相互作用. 他们不会预先承认自己没有给出重要的细节, 所以会使得读者以为他们了解了语言的全部. 当读者初次想要使用C++的一些技巧时, 他们将会为那些特性间的相互作用痛苦不堪. 另一类是试图给出所有有关相互影响的细节, 但这却会给人很大的压力. 许多学习C++的新手阅读过这些书后都会对这种语言产生恐惧感. 想到要完全掌握所有细节以及那些要记住的东西是很挫人土气的. 这是很不幸的. 因为C++完全可能让人觉得比较有趣, 而且绝对值得人们为之付出努力. 所需要的只是采取一种更为友好的方式来接近它.
我们的解决方案——采取子集
我们的解决方案就是写一本仅介绍C++特性子集的书. 这个子集包括”厂我们所认为的C++语言的核心特性(没有这些特性它就不再是C++)以及少数其他特性, 这样就可以使其成为合理化的有用语言. 我们努力避免加入太多的特性, 好让那些令人迷惑的相互作用不至使整个语言让人感到痛苦不堪. 初学C++的人可以通过这一子集来熟悉这门语言的基础, 间时还能避免产生沮决的感觉, 这种情况对于没有经过适当的准备就一头扎进C++程序设计中的人来说是很普遍的. 一且你熟悉了这门语言的基础, 就可以阅读一些其他的书籍, 以得到更为全面的内容.
我们认为初学者在读过本书之后, 就能从其他书籍中得到更多有用的东西. 我们所提供的子集并非是——种面向企业应用的程序设计语言. 我们是想使其成为学习经验的一部分. 它是为初学者学习语言的其余部分并且成为企业级的程序员而准备的. 它甚至不是一个精致的子集. 或者说它并不执行C++的精致之处. 听起来像是我们在试图逃避埋怨, 埋怨我们为什么不包括这个特性, 埋怨我们怎么能漏掉那个特性. 我们已经努力丁. 选择子集的过程是痛苦的. 各个特性在各种各样的应用程序中紧密地联系在一起, 这就是导致强烈的相互作用的原因, 也是剔除某个特性的难点所在. 就像从毛衣上抽出一根松了的线, 线会越来越长. 直到最后定稿, 在子集的何处进行分割一直是我们争论的主题. 虽然选择一个使所有人在任何时刻都满意的子集是不可能的, 我们仍然希望我们已经选择的是能够令学习C++的人感到更加愉快的部分.
为什么使用C++?
如果你不小心, 会在使用C++时遇到很多麻烦, 那么为什么还要使用C++呢?我们发现随着计算机的高度发展, 可以使用C++编写出更为精致的代码. 它使你可以提炼出各种任务的核心, 最为典型的就是内存管理. C可与之竞争的是运行时间, 但是其代码通常很难读. 其他的语言可以在精致程度上与之相竞争, 但是通常要以巨大的运行时间作为代价. 如果快速而又精致的代码对你来说很重要, 那么我们推荐你使用C++.
本书的构成
第一章“含类的面向对象程序设计”, 是对OOP的一个快速浏览, 这也是发明C++的原因. 在这里我们并不是要教你OOP, 这个主题足可以写几本书而不仅仅是一章. 你只需要浏览一卜以了解这本书.
第二章“不合类的C++”描述了C++的一些特性, 这些特性会使通常的程序设计更为简单易行.
第三章“成员函数产生的抽象性”描述丁C++的类. 类是C++的核心, 以至于C++的初始版本被称为“含类的C”.
第四章“存取说明符产生的封装性”描述了如何控制类中数据和因数的存取.
第五章“合并和派生产生的层次性”描述了C++中代码用的两种强大机制.
第六章“构造函数和析构函数产生的更好的抽象性”说明厂如何控制对象的构造和销毁.
第七章“new函数和delete函数产生的更好的抽象性”描述了C++提供的改进后的内存管理机制.
第八章“引用”回答了一“些诸如“什么时候指针不是指针”的问题.
第九章“由其他特殊成员函数产生的更好的抽象性”, 对第六章进行了补充, 描述了一些第六章所略去的具有特殊用途的成员函数.
第十章“一个示例类”展示了一个示例类的几种实现方案, 使用“了前一章所讲到的具有特殊用途的成员函数.
第十—‘章“模板产生的更好的层次性”对模板进行了描述, 它看起来像宏, 但是却更为安全和强大. 如果你和我们一样, 那么看到模板后就会想“这是一个多么可怕的组合”, 那么当你使用了一‘段时间之后, 又会想“这是一个多么有用的可怕组合”.
第十二章“虚函数产生的多态性”讲述了如何使用C++书写代码. 使得代码独立于它要操作的对象类型.
第十三章“进一步了解多态性”继续讲述了有关多态机制的一些更高级的特性.
第十四章“实现一个面向对象的设计”讨论厂与实现——个面向对象的设计有关的问题.
第十五章“一个示例程序”介绍了一个例程, 以说明我们的C++子集中的大多数特性.
第十六章“下—步要学习什么”对如何继续C++的学习提出了建议.
附录一“C++运算符”是为查询用的. 它提供了一个有关C++的运算符及其优先级的完整列表.
附录二“使用量值返回时产生的一个问题”讨论厂使用量值来传递类时遇到的一个问题, 如第八章介绍的那样.
本书的最后还有一个参考书目, 列出了有关C++的其他有用的书籍.
如何得到C++
C++是非常流行的, 你通常可以在买硬件的地方或者买软件的地方买到一个C++编译器. 如果买不到, 或者你想查找一些C++的其他资源(包括自由软件和共享软件), 可以试一下参考书目中列出的资源. 杂志和Internet是得到最新消息和推荐的地方. 我们之所以对是否提供这两个资源产生犹豫, 是因为在这个多变的市场中, 两者都变化得太快.
获取在线例程
本书的例程可以使用多种方式获得, 如使用FTP. ftpmail. BITFTP以及UUCP.
最廉价. 最快, 也是最简单的方法在最前面列出. 如果你从上到下阅读, 那么你所能使用的第一种方法就是最好的方法. 如果你直接在Internet上就使用FTP, 如果你不在Internet上, 但是可以通过Internet站点收发电子邮件(这包括服务器用户), 就使用ftpmail, 如果你通过BITNET发送电子邮件, 那就使用BITFTP, 如果以上方法都无法使用, 就使用UUCP.
PTP
要使用FTP, 你需要有一台可以直接访问Internet的计算机. 下面显示了一个例子, 黑体字部分是你应该键入的.
% ftp ftp.oreilly.com
Connected to ftp. oreilly. com.
220 FTP server (Version 6. 21 Tue Mar lO 22:O9:55 EST l992) ready.
Name (ftp. oreil1y. com:yourname):anonymous 33l Guest login ok send domain style e—mail address as password.
Password:username@hostname(在此输入你的电子邮件地址) 230 Guest login ok, access restrictions apply.
ftp> cd /published/oreil1y/nutshell/c.core 250 CWD command successful.
ftp>binary(你必须指定压缩文件为二进制形式)20O Type set to I.
ftp> get examples. tar. z
20O PORT command successful.
150 Opening BINARY mode date connection for examples. tar. z.
226 Transfer complete.
ftp>quit 22l Goodbye. %
该文件是一个压缩了的tar档案库. 键入如下的命令可以将文件从压缩文件中抽取出来:
% zcat examples.tar.z|tar|tar xyfSystem V则要求使用如下的tar命令:
% zcat examples.tar.z|tar xof如果你的系统不能使用zcat, 就使用单独的uncompress和tar或者sbar命令.
% uncompress examples.tar.z
% tar xyf examples.tar.z
ftpmail
ftpmail是一个任何人都可以使用的邮件服务器, 人们可以用它向Internet站点发送或从Internet接收电子邮件. 这些站点包括所有的允许电子邮件连接到Internet上的公司和服务提供者. 下面介绍如何使用它. 你需要将邮件发送到ftpmail@online. ora. com, 在消息主体部分给出你想要运行的FTP命令. 服务器会为你运行一个匿名的FTP, 并将文件寄回给你. 要得到一个完整的帮助文件, 就发送一条没有主题的消息, 并在主体部分注明help. 下面是一个邮件的示例, 它将使你得到例程. 其中的命令将会发送给你一份选定目录下的文件列表和所请求的示例文件. 如果你对一个例程的较新版本比较感兴趣, 那么这个列表将会非常有用.
%mail ftpmail@online.ora.com
Subject:
reply-to username@hostname(填入你想将文件寄到哪儿)
open
Cd /published/oreilly/nutshell/c.core
dir
mode binary
uuencode
get examples.tar.z
quit
可以在消息的最后加上签名, 但要把它放在“quit”之后.
BITPTP
BITFTP是给BITNET用户提供的一个邮件服务器. 你可以向它发送电子邮件以请求某些文件, 然后它就会通过电子邮件发送给你这些文件. BITFTP目前只为特定的用户服务, 这些用户的邮件是由那些直接在BITFTP. EARN或者NetNorth上的节点发出的. BITFTP是普林斯顿大学提供的公共服务. 下面介绍它是如何使用的.
要使用BITFTP, 就将包括你所需的ftp命令的邮件发送到BITFTP@PUCC. 要得到一个完整的帮助文件, 就将HELP作为消息主体.
下面是你发送给BITFTP的消息:
FTP ftp.oreilly.com NETDATE
DSSR anonymous
PASS username@hostname(输入你的Internet电子邮件地址,
而不是BITNET地址)
CD/published/oreilly/nutshell/c.core
DIR
BINARY
GET examples.tar.z
QUIT
如果你得到了想要的文件. 就可以根据FTP给出的指示将文件从文档库中抽取出来. 如果你使用的不是UNIX系统, 可能需要为系统添加uudecode. uncompress. atob和tar的版本. VMS. DOS和Mac的版本同样可用. VMS版本在gatekeeper. dec. com的/pub/VMS上.
有关BITFTP的问题可以访问Melinda Varian, 地址是BITFTP上的MAIN@PUCC.
UUCP
UUCP实际上在所有的UNIX系统中是很普遍的, 而且还适用于与IBM兼容的PC机, 以及Apple Macintosh机器. 你可以使用. UUCP通过调制解调器从UUNET处获得例程. 计费是以和UUNET的连接时间为依据的.
无论你在UUNET有没有户头, 你都可以从那里得到例程. 如果你或者你的公司在UUNET有户头, 你就会有一个具有UUCP和UUNET直接连接的系统. 找到该系统, 键人命令(在一行之中键人):
uucp uunet\!~published/oreilly/nutshell/c.core/examples.tar.z
(你的主机\!~/你的文件名/)
如果你使用的是Bourne shell(sh)而不是csh, 那么反斜杠可以省略. 一天之后或更久一些, 所需的文件应该出现在目录/usr/spoo1/uucppublic/你的文件名下.
如果你没有户头, 但是想开一个以便收发电子邮件, 请联系UUNET, 电话是(703) 204-8000.
试着去获取文件/ptlblished/oreilly/1s—1R. Z, 把它作为一个短小的测试文件, 它包括所有有效文件的文件名和大小, 这是个不错的主意.
当你得到了想要的文件时, 可以根据FTP给出的指示将文件从文档库中抽取出来.
约定
当对一个似乎排版实际与此不符或者当文件名出现在段落中时, 我们使用斜体字表示新术语和文件名. 对计算机输出的内容和源代码的片段, 我们使用CoMrler字体(等宽字体).
建议与评论
本书的内容都经过测试, 尽管我们做了最大的努力, 但错误和疏忽仍然是在所难免的. 如果你发现有什么错误, 或者是对将来的版本有什么建议. 请通过下面的地址告诉我们:
美国:
O’Reilly&As sociates, Inc.
10l Morrls Street
Sebastop01, CA 95472
中国:
100080北京市海淀区知春路49号希格玛公寓B座809室
奥莱理软件(北京)有限公司
询问技术问题或对本书的评论, 请发电子邮件到:
info@mail.oreilly.com.cn
最后, 您可以在WWW上找到我们:
http://www.oreilly.com
http://www.oreilly.com.cn
致谢
我们要向Joe Pruett, Ward Cullningham, Ron Lunde和Rob Daasch致以诚挚的谢意, 感谢他们专业性的建议和支持.
感谢我们的技术审校Brian T. Hill, Paul Kleppner, Barbara J. Wagreich, Andre A1gtIero, David Cohen, A11drew M1gliore, JeffYemin, Ken Dood, Dan Pasette和Giao Tran, 他们提供了许多有帮助的反馈. 特别要感谢Stan Lippman.
感谢Anne Pycha的评论. 注释和鼓励.
感谢我们的编辑Adrian Nye和O, Reilly&As sociates公司为使这本书成为现实付出努力的所有人. 包括本书的项目经理兼技术编辑Mary Anne Weeks Mayo,
负责将书稿从troff转成SGML的Len Muellner和E11en Siever, 他们处理工具的技巧真是惊人, 负责制图的Chrls Reilley, 封面设计Edie Freedman, 内文版式设计Nancy Priest, 封底设计Hanna Dyer, 索引制作Seth Maislin, 质量控制Kismet McDonough—Chan, 还有生产助理MichaelDeutsch.
Greg要感谢E1ectronic Book Techno1ogies公司, 我们俩都要感谢Summit Design公司, 感谢在公司工作期间公司对我们写书提供的支持. Greg还要感谢Portland Pretzel公司提供的友好而又有趣的休息环境.
最后, 特别感谢Jean DeMaiffe快递服务公司提供的完美服务.