设为首页 加入收藏

TOP

C++代码设计与重用 前言
2013-10-07 15:03:05 来源: 作者: 【 】 浏览:62
Tags:代码 设计 重用 前言

前言

一切事物都将得到检验并因此被称为问题。

Edith Hamilton

这本书的主要目的在于:展示如何以C++(www.cppentry.com)编程(www.cppentry.com)语言编写可重用代码-就是说,根据不同的需要,在不经过修改,或者经过很少修改的前提下,可重用代码可以很容易地应用到5个、50个甚至500个程序当中,而且这些程序往往是不同程序员编写的,可能运行在不同的系统上。在整个阐述的过程中,我们的目的并不在于争论是否所有的代码都是可重用的,也不在于说明可重用代码能够解决所有的程序问题。显然,不论是对程序员而言,还是对可重用代码本身而言,提高代码的重用性都是需要代价的;通常只有当我们有理由相信所给代码在将来有可能会被重用时,我们才会付出这些重用的代价。因此,本书的目的在于详细分析重用性的这些代价,于是当你面对是否编写可重用代码的选择时,可以从容地做出明智的决定。

关于本书

本书主要面向的读者是:那些希望从书中包含的许多深层C++(www.cppentry.com)编程(www.cppentry.com)见解中受益的读者,或者是那些需要或希望学习如何编写可重用代码的读者。在论述过程中,我们假设读者已经知道如何编写正确的C++(www.cppentry.com)代码。

C++(www.cppentry.com)语言至今还没有经过标准化(译注:本书写作于1995年,C++(www.cppentry.com)于1997年标准化),任意两个不同的编译器实现支持的语言几乎都是不同(稍微不同或者相差很大)的。当我编写这本书的时候,并没有一个编译器实现可以完全支持ANSI/ISO C++(www.cppentry.com)标准中最终定义的整个语言特性;而且,就算对同类型的编译器而言,前后版本实现的语言特性也不尽相同。于是,编写一本对所有编译器都适用的书是很困难的,或者是不可能的。因此,当我们讨论或使用一些不能被主流C++(www.cppentry.com)编译器所实现的特性时,我们将会另加说明。

当声明本书中的代码例子被认为合法时,我们所指的合法性是以1994年9月份ANSI/ISO C++(www.cppentry.com)的工作文件(有时候也称为"标准草案")[ANS94]为依据的。而且,在我们的代码例子里,我们将尽量避免使用那些我们认为在最终ANSI/ISO C++(www.cppentry.com)标准公布之前,很有可能会被删除或者进行重大修改的语言特性。

要跟踪C++(www.cppentry.com)语言的演化,有几个资源是可以利用的。Internet讨论组comp.lang.c和comp. std.c++主要致力于C++(www.cppentry.com)的讨论。互联网中还有一个关于C++(www.cppentry.com)的主页:

http://info.desy.de/user/projects/C++(www.cppentry.com).html

而由纽约SIGS出版社定期发行的C++(www.cppentry.com) Report,也经常会刊登许多C++(www.cppentry.com)程序员感兴趣的文章。至于学习C++(www.cppentry.com)的书籍,Lippman的[Lip91]和Stroustrup的[Str91]是最佳的学习教材。

任何关于重用性的完整讨论都会涉及软件开发的一些其他主题,如接口的设计、实现的效率、可移植性、冲突等。在书中的论述中,我们假设读者对软件开发已经有所了解;因此,我们只注重于那些应用于可重用代码的主题,而不是那些应用于一般软件开发的主题。

"每本教材都会撒谎",这是我们老师非常喜欢的一句谚语。在这里,她实际要表达的意思是:每本教材为了教学的简化性和明确性,都必须简化书中的内容,从而都会歪曲所要表达的信息。显然,即使在需要简化的前提下,我们还是应该用抓住众多细节间的本质信息的方法来表述每个主题,这本书也不例外。于是,对于某些主题,即使有些读者已经对这个主题的方方面面都有所了解,我们还是希望他们能够和我们一起共同探讨该主题的内容。而且,对于一些主题内容的省略,我们也希望能够得到这些读者的谅解。

选择与建议

设计和编写可重用代码将会涉及许多选择(即在多种实现方案中选定某种方案),而某些选择的决定又是左右为难的。通常,对于这些选择,并没有完全确定或者正确的答案-无论你做出哪个选择,每个选择都是有代价的。我们将讨论各种不同选择方案的优点和缺点,从而让将来可重用代码的编写者可以从容地做出明智的决定。

有时,对于某个给定的决定,我们会认为某种风格或者方法要优于其他所有的风格或者方法。于是,当遇到这种情况时,我们会明确地建议采用这种风格或者方法,并给出支持这种风格或者方法的详细理由。然而,在大多数情况下,只有C++(www.cppentry.com)程序库的设计者,才能决定哪种方法对程序库用户而言是最好的。

这本书的一个目的在于:详细并且清楚地给出编写可重用代码的大多数重要选择。如果我们忽略了某些重要的选择,那么我们愿闻其详。

书中大多数关于选择的讨论都会提到效率。虽然我们并不认为效率是所有可重用C++(www.cppentry.com)代码最重要的设计目标,因为对于许多程序库设计而言,譬如扩展性、灵活性等其他特性将会比效率更加重要;但我们在文章中又处处提到效率,这是因为效率将会和可重用C++(www.cppentry.com)代码的其他每个可取的特性都相互制约。既然对效率已经花费了这么多笔墨,我们也希望可以给出所有和效率相互制约的因素。

代码例子

我们希望这本书的价值在于:与刚开始读这本书之前相比,当你读完这本书的时候,你将知道更多关于如何编写可重用代码的知识。因此,我们使用了大量的例子,而且许多例子的代码是来自于现实中已经存在的代码,因为,那些不是取材于真实代码的例子,不足以阐明实际编程(www.cppentry.com)中会出现的问题,也不足以说明实际编程(www.cppentry.com)中使用的各种技术。在这里,我们只是为了阐明重用性的目的而利用这些代码。

为了节省篇幅,成员函数的主体通常都是在类的声明中给出;即使在重用性的代码设计中,这些函数也不会被实现为内联函数。例如,读者不应该从下面的类定义语句中得出:函数f是内联函数(就是说实际上f不是内联函数)的结论。

  1. class  Z  {  
  2.   void  f()  {  
  3.        //...  
  4.   }     
  5. }; 

(关于如何决定某个函数是否应该实现为内联函数,我们将在4.4.1节讨论这个问题)

当提到模板成员函数的时候,在不致引起混淆的前提下,我们通常都会省略模板参数。例如,我们将把下面代码中的成员函数f:

  1. template<class  T> 
  2. class  X  {  
  3.    void  f();  
  4. }; 

表示为X::f,而不是X<T>::f。

通常,现实程序库例子中给出的类大多是模板,而在书中,为了能够使阅读更加容易,并且有利于更加清楚地表述每个主题,我们就进行了简化。相似地,现实程序库中的嵌套类也并不都如嵌套语法所定义的那样,但是,当我们在书中给出一个嵌套类的时候,我们将不使用前置声明语法。例如,我们将如下编写嵌套类:

  1. class  X  {  
  2.   class  Y  {  
  3.      //...  
  4.   };  
  5. //...  
  6. }; 

而不是如下编写嵌套类:
  1. class  X  {  
  2.   class  Y;  
  3.     //...  
  4. };  
  5. class  X::Y  {  
  6.    //...  
  7. }; 

虽然前置声明语法能够提高可重用代码的可读性,但是许多C++(www.cppentry.com)编译器都不能实现这种语法。

现今,任何我们可用的编译器,都还没有实现新的强制转型(cast)语法。这个语法是一个很新的C++(www.cppentry.com)特性(针对于编写这本书的时候),我们也还不具备应用这个语法的充分经验,因此,我们在书中没有使用这个语法。

术语

在本文中,我们将使用程序库概念来表示可重用代码的集合。我们也经常互换地使用程序库和可重用代码这两个概念。另外,当我们说"编写"代码段的时候,我们的意思是"设计和实现"这段代码。

我们将使用编译程序来指代任何程序或者任何把源代码翻译成可执行代码的程序集合。翻译将包括:预处理C++(www.cppentry.com)使之成为另一种语言,然后把这种语言编译或者汇编成可执行代码。

为了行文简洁,我们在文章中使用的基类,不仅用来表述其他类的基类,而且还表述这个类可让其他类派生自该类。

C++(www.cppentry.com)操作符

  1. ostream&  operator<<(ostream&  o,const  T&  t);  
  2. istream&   operator>>(istream&  i,T&  t); 

(对于某个给定的类型T)提供了T类型的流插入和流输出操作符。为了和通常的使用习惯保持一致,我们把它们分别叫做T的输入操作符和输出操作符。

关于模板和模板实例化的术语,C++(www.cppentry.com)社区仍然有许多不一致的意见。不同的人可能会使用术语模板类、类模板、实例化、实例、特化等中的一个,来描述不同(或者相似)的事物。这些术语准确而且标准的定义最后将由ANSI/ISO C++(www.cppentry.com)委员会来决定。下面说明了我们在此书中如何使用这些概念:

类模板:形如template<…>X的模板,其中X为类的定义。

函数模板:形如template<…>f的模板,其中f为函数的定义。

类模板特化:当类模板的参数被实际参数替代时,而得到的类。

函数模板特化:当函数模板的参数被实际参数替代时,而得到的函数。

实例化:产生特化的过程。

模板类:我们不使用这个术语。

模板函数:我们不使用这个术语。

例如,考虑下面的类模板:

  1. template<class  T> 
  2. class  X  {  
  3.    //...  
  4. }; 

类X和类X就是这个模板的两个特化。另外,特化通常是隐式定义的,如:
  1. template<class  T>  class  X  {  /*...*/};  
  2. X<int> x;          //X<int>就是隐式定义的。 

偶尔,某些C++(www.cppentry.com)程序员也会显式定义特化,例如:
  1. template<class  T>class  X  {  /*...*/  };  
  2. class  X<int>    {/*...*/};    //X<int>在这里显式定义。  
  3. x<int>  x; 

而许多人把特化这个术语仅仅看成是显式特化,这是不正确的。虽然我们定义的这些术语都是非常相似的,但我们相信,ANSI/ISO很快将会给出这些术语很好的定义。

通常,在不会引起混淆的前提下,我们会使用"类"来代替"类模板","函数"来代替"函数模板"。

致谢

在这本书的创作过程中,许多人通过多种方式支持过我们。我们在这里对他们表示衷心的感谢。

这本书的评审者所做出的贡献和该书的价值几乎是等同的。我们特别感谢那些对我们要求严格的评论者,他们总是相信我们可以做得更好。这其中包括Tom Allocco、Manuel Bermudez、James Coggins、Keith Gorlen、Tony Hansen、Chris Hornick、Peter Juhl、Brian Kernighan、Andrew Koenig、Eason Kung、Rao Kuimala、Doug Lea、Stan lippman、Tom Lyon、Glen McCluskey、Barbara Moo、Rob Murray、Jishnu Mukerji、Scott Myers、Steve Pendergrast、Ed Schiebel、Jonathan Schilling、Jonathan Shopiro、Bjarne Stroustrup、Steve Vinoski、Jedy Ward和Clay Wilson。

我们也收到了许多读者很有用的反馈信息,他们是Dag Bruck,Rich Kempinski,Josee Lajoie,Deborah McGuinness,David C.Oliver,Jeffrey Persch,Ellia Weixelbaum和两个分别叫做Lars和Steve的网友。

这本书的许多观点首次来自于我们设计C++(www.cppentry.com)标准组件库的实践,这个组件库最初是由贝尔实验室开发的。因此,我们要感谢我们的同事们关于这个项目的许多有深度的讨论。他们是John Tsner, Andrew Koenig, Dennis Mancl, Rob Murray, Jonathan Shopiro,Alex Stepanov, Terry Weitzen和Nancy Wilkinson。

如果没有C++(www.cppentry.com),那么这本书(也包括其他的许多书)肯定是不会存在的。因此我们非常感谢Bjarne Stroustrup给我们带来了这样一个我们最喜欢的编程(www.cppentry.com)语言。另外也感谢ANSI/ISO C++(www.cppentry.com)标准委员会的所有成员,正是因为他们孜孜不倦的工作(往往都是自愿而且无功利的),才能使整个C++(www.cppentry.com)社区生机焕发。

感谢在我们这本书的编写过程中,我们这本书的审订者-Marha Currie,Barbara Moo和John Spicer-感谢他们的支持和鼓励。也感谢我们的雇主-贝尔实验室和UNIX系统实验室(现在是Novell UNIX系统小组)-感谢他们给了我们编写这本书的机会,而且还感谢他们为我们提供的时间、硬盘空间、打印纸等。

我们非常感谢来自Addison-Wesley的大力支持。其中,充满活力的Tom Stone和生性乐观的Debbie Lafferty都是很好的合作伙伴。另外,Lyn Dupre给了我们最好的编辑指导,书的设计者Juliet Silveri的工作总是一丝不苟,Pat Daly是一个很专业的编辑,Roberta Clark对我们的草稿进行了校对。我们还要感谢John Wait,正是因为他一贯坚持让Martin编写一本关于C++(www.cppentry.com)和重用的书,才会有这本书的诞生。然后,也很感谢Jim DeWolf,他为我们提供了暖气和空调,这笔支付也是不菲的,从而给我们带来了一个很好的环境和开端。

衷心感谢Tom Reinhardt,他可以说是世界上最好的外科临床医学家。也感谢我们的朋友Paul Lustgarten,他是我们以前的房东,很慷慨地允许我们时时占用他的电话线。还感谢David Wooley,正是他让Martin在大学中进入到BASIC编程(www.cppentry.com)领域中来的。真诚地感谢Marybeth为我们拍了书背面的那张照片。

最后,但也是很重要的,我们真诚感谢我们的家人和朋友,他们和我们度过了这本书编写过程中的许多酸甜苦辣的日子,并且时时刻刻给予我们支持与关怀。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++代码设计与重用 目录 下一篇4.3.2 外联的(outlined)inline

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: