最近開始重新的寫C++ code...哀幾乎都忘光了!



From: bs@alice.att.com (Bjarne Stroustrup)
Newsgroups: comp.os.msdos.programmer,
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?


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、assembler等等有個徹底的認識,然後將在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++?

我要進行OOP(物件導向程式設計),需不需要在學C++之前先學 Smalltalk?

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?


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.

To learn C++ use:

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++?


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?


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++?


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

注意到學習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

以細心觀看C++定義細節的方式來看看設計合同 - 通常使用 ARM:
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


文章出處: C++ Gossip

創作者 philip 的頭像

Philippe's Expérience Note

philip 發表在 痞客邦 留言(0) 人氣()