BBS水木清华站∶精华区

发信人: william@cis_nctu (C++/ASM/Win Master), 信区: oop 
标  题: 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. 
 
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. 
 
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++? 
 
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++. 
 
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). 
 
To show my inclinations: 
 
To learn C use: 
 
Kernighan and Ritchie: 
The C programming Language (2nd edition) 
Prentice Hall, 1988. 
 
as the primary textbook. To learn C++ use 
 
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++? 
 
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. 
 
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++. 
 
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''). 
 
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. 
 
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. 
 
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. 
 
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. 
 
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. 
 
 
 
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. 
 
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. 
 
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++ 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. 
 
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++. 
 
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. 
 
 
 
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.'' 
 
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. 
 
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. 
 
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 
 
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? 
 
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. 
 
- Bjarne Stroustrup 
 

BBS水木清华站∶精华区