C++ 之父给初学者的信


C++ 之父给初学者的信
From: bs@alice.att.com (Bjarne Stroustrup)
Newsgroups: comp.os.msdos.programmer,
comp.sys.ibm.pc.programmer,
comp.lang.c++,comp.lang.c
Subject: Newbie Wants Advice on C-Programming
Summary: general comments on learning C++
Date: 29 Dec 92 17:52:53 GMT
Organization: AT&T Bell Laboratories, Murray Hill NJ
Lines: 288

There has - under various headings - been several related discussions about the proper way to learn C++, C++'s relation to C, C++'s relation to Smalltalk, the difference (or not) between data abstraction and object-oriented programming, etc.

虽然标题不同,不过跟 C++ 学习相关的讨论也出现过很多次了,例如 C++ 与 C 的关联,C++ 与 Smalltalk 的关系,数据抽象与面向对象程序设计的不同等。

I think the practical concern underlying many of these discussions is:
Given that I don't have much time to learn new techniques and concepts, how do I start using C++ effectively?

我觉得这些讨论实际上的重点是:如果没时间学新技巧或观念的话,如何才能快速上手 C++?

It is clear that to use C++ ''best'' in an arbitrary situation you need a deep understanding of many concepts and techniques, but that can only be achieved through years of study and experiments. It is little help to tell a novice (a novice with C++, typically not a novice with programming in general), first to gain a thorough understanding of C, Smalltalk, CLOS, Pascal, ML, Eiffel, assembler, capability based systems, OODMBSs, program verification techniques, etc., and then apply the lessons learned to C++ on his or her next project. All of those topics are worthy of study and would - in the long run - help, but practical programmers (and students) cannot take years off from whatever they are doing for a comprehensive study of programming languages and techniques.

显然地,想随时随地都善加利用 C++ 的话,得深入理解许多观念与技巧,而这是多年学习与实现才有可能获得。告诉初学者(C++ 初学者,一般来说,不会是程序语言的初学者):「要先有 C、Smalltalk、CLOS、Pascal、ML、Eiffel、组语、能力基础系统、OODMBS、程序验证技巧等,接着在下个项目中使用 C++ 中学到的东西」这种说法没什么用。这些主题都值得研究,而且确实也各有其应用场合,不过实务上,程序设计者(与学生)不可能丢下手边的工作,只为了全面研究程序语言及技巧。

On the other hand, most novices understand that ''a little knowledge is a dangerous thing'' and would like some assurance that the little they can afford time to learn before/while starting their next project will be of help and not a distraction or a hinderance to the success of that project. They would also like to be confident that the little new they can absorb immediately can be part of a path that can lead to the more comprehensive understanding actually desired rather than an isolated skill leading nowhere further.

另外,多数初学者都知道「一知半解的危险性」,因此想要某种程度的确认,现在付出的这一丁点时间学到的东西,能在接下来的项目派上用场,或者至少别拖累,造成项目的困扰。他们也想要的是,吸收到的这些东西,对于最后真正想全面理解的东西,会是有益的,而不只是用来解决眼前问题的独立性技巧。

Naturally, more than one approach can fulfill these criteria and exactly which to choose depends on the individual's background, immediate needs, and the time available. I think many educators, trainers, and posters to the net underestimate the imporatance of this: after all, it appears so much more cost effective - and easier - to ''educate'' people in large batches rather than bothering with individuals.

当然,是有些方法能符合这些考量,至于选用哪个方法,则依个人的背景、立即需求与可用的时间来决定。我想许多教育者、训练师或以及海报都低估了这个重要性:毕竟,教一群人显然比较有效益,也比较轻松。

Consider a few common questions:
I don't know C or C++, should I learn C first?
I want to do OOP, should I learn Smalltalk before C++?
Should I start using C++ as an OOPL or as a better C?
How long does it take to learn C++?

来看几个常见的问题:
我不懂 C 或 C++,要不要先学 C?
我想写面向对象程序,要不要先学 Smalltak 再学 C++?
要把 C++ 当面向对象语言用吗?或者是更好的 C?
学 C++ 要花多久时间?

I don't claim to have the only answers ''the (only) right answers'' to these questions. As I said the ''right'' answer depends on the circumstances. Most C++ textbook writers, teachers, and programmers have their own answers. For example, I seem to remember that the C++ FAQ discusses these questions. My answers are based on years of programming in C++ and other languages, teaching short C++ design and programming courses (mainly to professional programmers), consulting about to introduction of and use of C++, discussing C++, and generally thinking about programming, design, and C++.

这些问题对我来说,都不会只有唯一的答案-(唯一)正确的答案。就我而言,「正确」答案都是视情况而定。多数 C++ 教科书的作者、教师、程序设计者也各有其答案。例如,我记得 C++ FAQ 好像也讨论过这些问题。我的回答会是基于在 C++ 与其他语言有多年设计经验、教过一小段 C++ 设计与程序设计课程(对象主要是专业的程序设计者)、作过 C++ 导入与使用的顾问、C++ 的讨论、经常思考程序、设计与 C++ 等。

I don't know C or C++, should I learn C first?

我不懂 C 或 C++,要不要先学 C?

No. Learn C++ first. The C subset of C++ is easier to learn for C/C++ novices and easier to use than C itself. The reason is that C++ provides better guarantees than C (stronger type checking). In addition, C++ provides many minor features, such as the `new' operator, that are notationally more convenient and less error-prone than their C alternatives. Thus, if you plan to learn C and C++ (or just C++) you shouldn't take the detour through C. To use C well, you need to know tricks and techniques that aren't anywhere near as important or common in C++ as they are in C. Good C textbooks tends (reasonably enough) to emphasize the techniques that you will need for completing major projects in C. Good C++ textbooks, on the other hand, emphasizes techniques and features that lead to the use of C++ for data abstraction and object-oriented programming. Knowing the C++ constructs, their (lower-level) C alternatives are trivially learned (if necessary).

不!直接学 C++。C++ 的 C 子集对 C/C++ 初学者来说比较容易,比使用 C 本身还比较容易。原因在于,C++ 提供了比 C 更多的安全性(强类型检查)。除此之外,C++ 还提供了许多小特性,像是new运算符,这明显比 C 中对应的功能方便且更能避免错误。因此,如果想学 C 与 C++(或只要 C++),不用迂回地从 C 开始学,C 要用得好,会需要知道一些技法与技巧,而这些在 C++ 中不像在 C 那么重要与常见,好的 C 教科书会(适度地)强调完成一个大型 C 项目需要的技术,相对地,好的 C++ 教科书会强调的技巧与特性,在于运用 C++ 进行数据封装、面向对象程序设计。了解了 C++ 的结构,它们在(低阶)C 的对应部份自然也就学会了(如果有需要的话)。

To show my inclinations:
To learn C use:
Kernighan and Ritchie:
The C programming Language (2nd edition)
Prentice Hall, 1988.

我个人的偏好是:
要学 C 的话,用这一本书:
Kernighan and Ritchie:
The C programming Language (2nd edition)
Prentice Hall, 1988.

To learn C++ use:
Stroustrup:
The C++ programming Language (2nd edition)
Addison Wesley, 1991.

要学 C++ 的话用这本:
Stroustrup:
The C++ programming Language (2nd edition)
Addison Wesley, 1991.

Both books have the advantage of combining a tutorial presentation of language features and techniques with a complete reference manual. Both describes their respective languages rather than particular implementations and neither attempts to describe particular libraries shipped with particular implementations.

这两本的优点是可作为程序语言教学与技术参考手册,说明各自的语言而非特定实现,不会说明特定实现才有的特定程序库。

There are many other good textbooks and many other styles of presentation, but these are my favorites for comprehension of concepts and styles. It is always wise to look carefully at at least two sources of information to compensate for bias and possible shortcommings.

是有许多其他不错的教科书与呈现方式,不过就观念与风格的互补性来看的话,这两本是我的最爱。详细地看过两个以上的信息来源总是明智的,在一些偏重或可能的缺点才能互补。

I want to do OOP, should I learn Smalltalk before C++?

我想写面向对象程序,要不要先学 Smalltak 再学 C++?

No. If you plan to use C++, learn C++. Languages such as C++, Smalltalk, Simula, CLOS, Eiffel, etc., each has their own view of the key notions of abstraction and inheritance and each support them in slightly different ways to support different notions of design. Learning Smalltalk will certainly teach you valuable lessons, but it will not teach you how to write programs in C++. In fact, unless you have the time to learn and digest both the Smalltalk and the C++ concepts and techniques, using Smalltalk as a learning tool can lead to poor C++ designs.

不!如果想学 C++,就学 C++。像 C++、Smalltalk、 Simula、CLOS、Eiffel 等的程序语言,对于抽象、继承等上,各有其观点,而这些程序语言在不同特性的支持上会有一些差异,学习 Smalltalk 当然会得到不少宝贵的观念,但是它不会告诉你怎么用 C++ 写程序,事实上,除非你有时间学习、消化 Smalltalk 与 C++ 两者的观念与技术,不然以 Smalltalk 作为学习工具,对 C++ 的设计没有太大帮助。

Naturally, learning both C++ and Smalltalk so that you can draw from a wider field of experience and examples is the ideal, but people who haven't taken the time to digest all the new ideas often end up ''writing Smalltalk in C++'' that is applying Smalltalk design notions that doesn't fit well in C++. This can be as sub-optimal writing C or Fortran in C++.

当然,最理想的是 C++ 与 Smalltalk 都学,以便从更广的领域中获取更多经验与实证,不过在还没有时间消化全部的新想法前,通常就会变成「在 C++ 中写 Smalltalk」,也就是说将 Smalltalk 设计中一些不是很符合 C++ 特性部份拿来套用,这就像在 C++ 中写 C 或是 Fortran 同样地不理想。

One reason often quoted for learning Smalltalk is that it is ''pure'' and thus force people to think and program ''object oriented.'' I will not go into the discussion about ''purity'' beyond mentioning that I think that a general purpose programming language ought to and can support more than one programming style (''paradigm'').

学 Smalltalk 常见的理由是,它很「纯」,并且能迫使人们以面向对象的方式思考与设计程序。在讨论「纯」之前,应该先谈到的是,我认为通用型的程序语言,应该能支持一种以上的程序设计风格(模式)。

The point here is that styles that are appropriate and well supported in Smalltalk are not necessarily appropriate for C++. In particular, a slavish following of Smalltalk style in C++ leads to inefficient, ugly, and hard to maintain C++ programs. The reason is that good C++ requires design that takes advantage of C++'s static type system rather than fights it. Smalltalk support a dynamic type system (only) and that view translated into C++ leads to extensive unsafe and ugly casting.

这边的重点在于,Smalltalk 中适当的风格,在 C++ 不一定适合,在 C++ 中毫无创意地遵从 Smalltalk 风格,会有效率不良,令 C++ 程序难以维护的问题,原因在于好的 C++ 要利用到 C++ 静态类型系统的设计,而不是抗拒它。Smalltalk(只)支持动态类型系统,而这些观点转移至 C++ 将发生广泛的安全性与丑陋的类型转换问题。

I consider most casts in C++ programs signs of poor design. Some casts are essential, but most aren't. In my experience, old-time C programmers using C++ and C++ programmers introduced to OOP through Smalltalk are among the heaviest users of casts of the kind that could have been avoided by more careful design.

我认为 C++ 程序中多数的类型转换都是不良设计的表现,有一些转型是必要的,但大部份并非如此,就我的经验得知,一些过去使用 C 的 C++ 程序设计者,以及从 Smalltalk 进入 OOP 世界的人,都是这类类型转换的使用者,而他们可以更细心地设计以避免(这些不良设计)。

In addition, Smalltalk encourages people to see inheritance as the sole or at least primary way of organizing programs and to organize classes into single-rooted hierarchies. In C++, classes are types and inheritance is by no means the only means of organizing programs. In particular, templates is the primary means for representing container classes.

除此之外, Smalltalk 鼓励人们视继承为组织程序的灵魂,或至少是主要方法,将类组织为单根的体系。在 C++ 中,类是类型,而继承无论如何都不会是组织程序的唯一方法,尤其是,模版会用来表现容器类。

I am also deeply suspicious of arguments proclaiming the need to FORCE people to write in an object-oriented style. People who don't want to learn can, on average, not be taught with reasonable effort and there is in my experience no shortage of people who DO want to learn. Unless you manage to demonstrate the principle behind data abstraction and object-oriented programming all you'll get is inappropriate ''barouque'' misuses of the language features that support these notions - in C++, Smalltalk, or whatever.

我也很怀疑那些宣称必须以面向对象风格编写程序的论调。平心而论,对于拒绝学习的人,没办法教他们得付出努力,而就我的经验来说,这种不想学习的人不少。除非你想强调数据抽象化与面向对象程序设计背后的原则,否则 C++、Smalltalk,或其他支持这些概念的语言特性,最后只会是「巴洛克式」的误用。

See ''The C++ Programming (2nd Edition)'' and in particular Chapter 12 for a more thorough discussion of the relation between C++ language features and design.

看看《The C++ Programming (2nd Edition)》,尤其是第 12 章关于 C++ 特性及设计的讨论。

Should I start using C++ as an OOPL or as a better C?

要把 C++ 当面向对象语言用吗?或者是更好的 C?

That depends. Why do you want to start using C++? The answer to that question ought to determine the way you approach C++; not some one-size-fits-all philosophy. In my experience the safest bet is to learn C++ ''bottom up,'' that is first learn the features C++ provides for traditional procedural programming, the ''better C'' sub-set, then learn to use and appreciate the data abstraction features, and then learn to use class hierarchies to organize sets of related classes.

这得视情况而定,为什么你要用 C++ 呢?这问题的答案决定了你怎么用 C++,不过不是一体适用的的哲学。就我的经验来说,最安全的押注方式是「自底而上」学习 C++,也就是说先学 C++ 在传统程序设计上提供的特性 - 「更好的 C 子集」,然后学着使用与理解数据抽象化的特性,并且学着使用类体系来组织相关的类集合。

It is - in my opinion - dangerous to rush through the earlier stages because there is too high a probability of missing some key point.

以我的观点来说,匆忙略过初阶部份很危险,因为很可能跳过了关键的部份。

For example, an experience C programmer might consider the ''better C'' subset of C ''well known'' and skip the 100 pages or so of a textbook that describes it. However, in doing so he might miss the ability to overload functions, the difference between initialization and assignment, the use of the `new' operator for allocation, the explanation of references, or some other minor feature in such a way that it will come back to haunt him at a later stage where sufficient new concepts are in play to complicate matters. If the concepts used in the better C subset are known the 100 pages will only take a couple of hours to learn and some details will be interesting and useful. If not, the time spent is essential.

例如,有经验的 C程序设计者可能自认为熟悉 C,误以为熟知 C++ 中「更好的 C 子集」,就跳过了书本中描述这部份的 100 多页,然而这么作,可能会忽略函数重载的能力、配置时new运算符的使用、参考的说明、或一些其他小特性,以至于后续还必须回想这些复杂的东西是在哪出现的。如果已经知道更好 C 子集的观念,学习这 100 多页只会花几个小时,有些细节是有趣且有用的,即使不是这样,也是得付出这些时间。

Some people have expressed fear that this ''gradual approach'' leads people to write in C style forever. This is of course a possible outcome, but nowhere as likely as proponents of ''pure'' languages and proponents of the use of ''force'' in teaching programming like to believe. The key thing to realize is that using C++ well as a data abstraction and/or object-oriented language requires the understanding of a few new concepts that have no direct counterpart in languages such as C and Pascal.

有些人表示,他们怕这种「渐进方式」会使得人们使用 C 风格来写程序,这确实是有可能,不过这会是程序教学上「纯」语言支持者与发挥「能力」支持者的信仰问题,关键在于必须了解,要在数据抽象化与(或)面向对象程序语言上善加利用 C++,必须要认识一些新观念,而这些新观念与一些语言,例如 C 与 Pascal 之类的语言没有直接关联。

C++ isn't just a new syntax for expressing the same old ideas - at least not for most programmers. This implies a need for education, rather than mere training. New concepts have to be learned and mastered through practice. Old and well-tried habits of work have to be re-evaluated, and rather than dashing of doing things ''the good old way'' new ways have to be considered - and often doing things a new way will be harder and more time-consuming than the old way - when tried for the first time.

C++ 不只是一些用来表现老旧想法的新语法,至少对多数程序设计者来说不是,在教授上也需如此,不能只是单纯的训练。必须学习新观念并透过练习来掌握,在工作上既有的良好习惯必须要再度提炼,不能只是「既有的良好方法」之延伸,必须考虑新方法,在首次尝试时,用新方法是会有点难,也往往会比用旧方法来得费时。

The overwhelming experience is that taking the time and making the effort to learn the key data abstraction and object-oriented techniques is worth while for almost all programmers and yields benefits not just in the very long run but also on a three to twelve month timescale. There are benefits in using C++ without making this effort, but most benefits requires the extra effort to learn new concepts - I would wonder why anyone not willing to make that effort would switch to C++.

经验几乎都是如此,付出时间与努力学得的关键数据抽象化与面向对象技巧,对大多数程序设计者绝对值得,而产生的效益最终还能持续三到十二个月的时间。使用 C++ 时是有些不费力就可得到的好处,但大多数的好处,得付出额外心力学习新观念才能获得。我觉得奇怪的是,为什么有人觉得可以不费力地转换至 C++。

When approaching C++ for the first time, or for the first time after some time, take the time to read a good textbook or a few well chosen articles (the C++ Report and the C++ Journal contain many). Maybe also have a look at the definition or the source code of some major library and consider the techniques and concepts used. This is also a good idea for people who has used C++ for some time. Many could do with a review of the concepts and techniques. Much has happened to C++ and its associated programming and design techniques since C++ first appeared. A quick comparison of the 1st and the 2nd edition of ''The C++ Programming Language'' should convince anyone of that.

第一次接触 C++,或是一段时间之后又再度接触 C++ 时,请花点时间看本好书或是精选文章(C++ Report 与 C++ Journal Contain 有很多),也许看些主函数库的定义与源码,并思考当中使用的技巧与观念,这对用过 C++ 的人来说也是个不错的主意,可以复习对观念与技巧,在 C++ 首次问市之后,期间 C++ 又发生了不少事,而相关的程序编写与设计技巧也有所改变,比较一下《The C++ Programming Language》第 1 版与第 2 版的差异,任何人都会相信这点。

How long does it take to learn C++?

学 C++ 要花多久时间?

Again, that depends. It depends both on your experience and on what you mean by ''learning C++.'' The syntax and basics for writing C++ in the better C style plus defining and using a few simple classes takes a week or two for a programmer. That's the easy part. The main difficulty, and the main fun and gain comes from mastering new design and programming techniques. Most experienced programmers I have talked with quotes times from a half year to one and a half year for becomming really comfortable with C++ and the key data abstraction and object-oriented techniques it supports. That assumes that they learn on the job and stay productive - usually by programming in a ''less adventurous'' style of C++ during that period. If one could devote full time to learning C++ one would be comfortable faster, but without actual application of the new ideas on real projects that degree of comfort could be misleading. Object-oriented programming and object-oriented design are essentially practical - rather then theoretical - disciplines. Unapplied, or applied only to toy examples, these ideas can become dangerous ''religions.''

同样地,视情况而定,这依经验以及所谓「学 C++」是什么而定,以更好的 C 风格而言,必要的语法及基础,加上定义与使用一些简单类来写 C++,对程序设计者来说得花上一到两星期的时间,这还只是简单的部份,主要的困难、乐趣及收获,来自于新设计与程序编写技巧,我遇过的有经验程序设计者,多半花了半年至一年半的时间,才能真正熟悉 C++ 与其支持的关键数据抽象化与面向对象技巧。这是他们仍在职且持续保有生产力的假设前题下 - 这段时间通常以「较不冒险」的 C++ 风格编写程序。如果有人能全心付出时间来学 C++,是能更快熟悉,不过无法在实际项目上使用新想法会令人不安。以面向对象编写程序以及面向对象设计基本上是实务(而不是理论)法则,无法应用或者只应用在一些玩具般的案例,这些想法可能变 成危险的「教条」。

Note that learning C++ is then primarily leaning programming and design techniques, not language details. Having worked through a good textbook I would suggest a book on design such as Grady Booch:
Object Oriented Design with examples
Benjamin Cummings 1990.

注意,学 C++ 主要是在学习程序编写与设计技巧,而不是语言细节,在看过一本好书后,设计上我再建议 Grady Booch 这本:
Object Oriented Design with examples
Benjamin Cummings 1990.

which has the nice property of having longish examples in five different languages (Ada, CLOS, C++, Smalltalk, and Object Pascal) and is therefore somewhat immune to the language biogotry that mar some design discussions. The parts of the book I like best is the presentation the design concepts and the example chapters.

这本不错的地方是,使用了五种不同的程序语言(Ada、CLOS、C++、Smalltalk 与 Object Pascal)编写了的略长范例,因而可避免因语言差异而损失了一些设计讨论,这本书我最喜欢的部份,是设计观念的表现方式与范例章节。

Looking at design contrasts sharply with the approach of looking very carefully at the details of the definition of C++ - usually using the ARM:
Ellist&Stroustrup
The Annotated C++ Reference Manual
Addison-Wesley, 1990

重视 C++ 定义在设计上要如何实现的话 - 通常可以看 ARM:
Ellist&Stroustrup
The Annotated C++ Reference Manual
Addison-Wesley, 1990

which is a book containing much useful information, but no information about how to write C++ programs. A focus on details can be very distracting and lead to poor use of the language. You wouldn't try to learn a foreign language from a dictionary and grammar, would you?

这本书是有很多内容,不过没有谈到怎么写 C++。对细节的着重令人注意力不集中,而且很少谈到语言的运用。要学习一门外国语,应该不会想从字典及文法书开始吧?你会吗?

When learning C++, it is essential to keep the key design notions in mind so that one doesn't get lost in the language technical details. That done, learning and using C++ can be both fun and productive. A little C++ can lead to significant benefits compared to C, further efforts to understand data abstraction and object-oriented techniques yields further benefits.

在学 C++ 时,基本上要记得关键的设计概念,才不会迷失在语言的技术细节之中,这么作的话,C++ 的学习与运用才会有趣而具有生产力,只要一点点的 C++,就能比使用 C 得到更多好处,进一步地认识数据抽象化与面向对象技巧,则能获得更多的效益。

  • Bjarne Stroustrup



展开阅读全文