When OOP and C++ were still new to the mainstream, there emerged a tremendous need on the part of programmers for books on C++. Five years or so ago, a familiar question in online forums was, I want to learn more about C++, where do I start? It's a sign of the times (as well as of the decade we live in) that today, the question often is, I'll be laid off next month unless I learn C++, where do I start?
In response to this perceived need, book publishers unleashed a mountain of books on C++. A search through the Computer Literacy bookstore Web site (http://www. clbooks.com) now returns 376 books with "C++" in the title.
Leafing through a few of these books, you'll notice that some bear the earmarks of haste: superficial coverage of the topic, example code that will not compile, sundry misconceptions, and nuggets of misinformation. On occasion, it seems that the author is only a few weeks ahead of the reader in grasping the subject.
Some time ago, Andrew Schulman suggested a useful rule of thumb in weeding out the Johnny-come-lately novices from dyed-in-the-wool mavens: Consider only titles whose authors worked at or were once affiliated with Bell Labs. This filter would include worthwhile books by Bjarne Stroustrup, Margaret Ellis, Stan Lippman, Rob Murray, Jim Coplien, Stephen Dew-hurst, Kathy Stark, Andrew Koenig, Tom Cargill, Jonathan Shapiro and Martin Carroll, which should be plenty. The premise behind this rule is that C++ is a complex enough subject that only someone with years of hands-on experience can contribute useful advice, and for a long time, the only place one could get this experience was at Bell Labs. Obviously, this premise is less valid as C++ becomes more entrenched in the mainstream; even in times past, the stringent rule may have slighted some illuminating introductory treatments by outsiders. Nevertheless, I've found Schulman's suggestion useful when approaching a bookstore's sagging shelves.
More recently, I've been considering a different rule of thumb: Never read anything you can't lift. Okay, I've had to break this rule, but let me explain its rationale.
There's been an arms race among book publishers to make titles as physically wide as possible, to garner every last inch of shelf space and edge out competitors. This has resulted in overweight tomes of 800 pages or more, usually specific to a particular compiler or operating system, often released within a few weeks of the compiler's initial shipment, yet claiming to be the last word on the subject. Too often, you find inside a rehash of the vendor documentation, some toy programs, a few homilies, and well-worn bits of advice. The tips and suggestions therein take everything at face value, with little attempt to go beyond the manufacturer's feature list; there are few of the hard-won lessons that only extensive experience can provide.
As a result, I'm drawn to slim books that carry more than their weight in knowledge and insight--classics such as Scott Meyer's Effective C++ (Addison-Wesley, 1992), or James Coplien's Advanced C++ Programming Styles and Idioms (Addison-Wesley, 1992). These books cover material less likely to become obsolete with a new version of a particular compiler. C++ beginners have for a long time been well served by Stan Lippmann's C++ Primer (Addison-Wesley, 1991) and Stephen Dewhurst and Kathy Stark's Programming in C++, Second Edition (Prentice-Hall, 1995). These four books together take up about the same shelf space as one overweight, underpowered title.
However, C++ continues to advance, and more programmers are involved in multiperson projects whose codebase evolves over time. Once you've learned the syntax and some language tips, object-oriented design becomes more of a concern. One recently released book that satisfies a range of needs is Mastering Object-Oriented Design in C++, by Cay Horstmann. The book lives up to its billing on the jacket: "Everything you need in one manageable package!" In this small-format volume, Horstmann provides both an introduction to the C++ language and a "minimethodology" for object-oriented design that emphasizes tractable, real-world use instead of the ivory-tower overkill that some methodologies promote.
Horstmann is a man of few words, and he has packed just about every page in this book with useful information. The brevity is refreshing, and the clean and concise approach contrasts favorably with more-weighty tomes. For example, one popular C++ book has a 60-page chapter on pointers that begins around page 400. Horstmann dispenses with the subject in all of two pages. There are no long-winded explanations, drawn-out examples, padding of the book with page after page of repetitive listings, or half-page diagrams fluffed up with the currently fashionable 3-D, graduated-tint screens. The graphic design is as efficient and precise as the prose. There are many code fragments, usually two or three per page, woven naturally into the fabric of the discussion. Horstmann's book covers features recently added to C++, including exceptions, templates, namespaces, and run-time type. This coverage is not tacked on at the end, but is clearly part of the author's coding repertoire.
Horstmann makes his points in a no-nonsense fashion that is sometimes opinionated but whose opinions carry the weight of experience. For example, when talking about adding new operations to an existing class implementation: "Public data and cluttered interfaces must be avoided. You have no good choice but to stop coding your immediate task and to reexamine the overall class design."
Every chapter ends with a list of design hints: "Don't pollute the global namespace with constants," "A class that has a destructor needs both a copy constructor and an assignment operator," "Beware of constructors with a single integer argument," and "Class types are the norm; challenge basic types." These epigrams are followed by a one- or two-paragraph explanation.
Horstmann meticulously adheres to a coding style that "stays away from a good number of C++ features I consider of marginal value (such as private inheritance or pointers to member functions)." He acknowledges that coding preferences can be a matter of intense debate, and provides a 20-page appendix that lays out the guidelines formally so that you can modify them for personal or local taste.
If he sounds like a stern schoolmaster, perhaps that's because he is. Horstmann teaches computer science at San Jose State University in California, and this book has been designed for classroom teaching as well as personal use. Every chapter has exercises that go beyond the rote repetition you may have encountered in school. For example, Exercise 13.1.1 is: "Try corrupting the free list on purpose to see what happens on your system. Delete the same pointer twice. Then allocate pointers and check for duplicates or just for crashes."
The writer is more than a detached academic. Not mentioned in the book is the fact that Horstmann is author of a commercial word-processing package for scientific documents called "ChiWriter." This complex program has served as proving ground for the author's design hints and coding tips.
Recently, I've encountered programmers who have already completed the slow march up the learning curve of C++ and are ready to embark on a project involving Microsoft Visual C++ (MSVC) and Microsoft Foundation Class (MFC), only to find themselves at sea in a new ocean of information: the 80,000 lines of dense C++ code that comprise MFC, and the way this codebase interacts with the underlying Windows API. Having been in the same boat, I empathize strongly.
In contrast with the general topic of C++, there are very few independent sources of information on MSVC and MFC. One possible explanation, again, has to do with the complexity of the subject. Unless you work at Microsoft, you probably have not had the opportunity to work extensively with the latest compiler versions, given the rapid release rate of the languages division there.
The bulk of published material on this topic originates from Microsoft--the documentation, tutorials, tech notes and sample code packaged with its compiler and also found on the Microsoft Developer Network CD-ROM (MSDN). There is also the Microsoft Press book, Inside Visual C++, Second Edition, by David Kruglinksi (covering MSVC 1.5 and MFC 2.5). Fortunately, all these official works are of uniformly high quality and go a long way towards providing the "tribal knowledge"--the accumulated wisdom about tips, traps, and techniques--necessary for being productive in a complex environment. The Books Online information packaged with MSVC, plus the additional information in the MSDN CD, is essential for any developer working on the Windows platform, even if you use another vendor's compiler. Having the material in electronic form facilitates browsing and searching, although it does hinder extended reading. If you have a laser printer, however, it's easy enough to print out even entire chapters for offline perusal.
But what happens if your programming problem is not mentioned in this material? For example, I recently wanted to use the CPropertySheet class in MFC to implement a "tabbed dialog" app in 16-bit Windows. This class is supported in MSVC 2.1 for Windows 95 and Windows NT, but the 16-bit compiler (MSVC 1.5) isn't mentioned anywhere in the class reference docs. It turns out that CPropertySheet works fine with V1.52 or later; you just use it in the same manner as in V2.1. To find this out, I had to break my small-is-beautiful rule and consult some wide and heavy books.
I was pleasantly surprised by the quality of the Kruglinski book and of three other recent books on MSVC and MFC: Win32 Programming using Visual C++, by Mike Blaszczak; Visual C++ How-To, by Scott Stanfield et al.; and Visual C++ 2, by Marshall Brain and Lance Lovette. All are safe choices and provide good hard-copy coverage of MSVC and MFC, although none contain information that goes substantially beyond the product documentation. The Kruglinski, Blaszczak, and Brain/Lovette books all follow the traditional approach of covering the MSVC package on a component-by-component basis, with a chapter on, say, AppWizard, another on dialogs, one on ODBC, and so on.
The Visual C++ How-To is distinguished by its question-oriented problem-solving approach. There is no overview or introductory material; instead, the book presents a list of very specific questions, such as "How do I write a customized DDX/DDV routine?" or "How do I display a progress meter in the status bar?". Each question is answered in a half-dozen or so pages, which contain step-by-step instructions for adding lines of code to compiler-generated source files. (As you perhaps know, much of MFC programming involves interacting with Class Wizard and related code generators.) Because of this approach, Visual C++ How-To complements the other three books--think of it as additional Tech Notes that Microsoft did not write.
If I had to pick only one of the other three, I'd choose Win32 Programming using Visual C++. Perhaps because Blaszczak was part of the MFC development team, his book seems to have that extra modicum of insight into the design motives behind some MFC constructs. He does first restate the party line, which is that you don't need to know how MFC (or any other app framework) works in order to use it. But then he admits that when things go wrong, everyone feels the need to understand the internals behind mechanisms such as message maps or DDX/DDV tables. Although the book has a more conventional purpose than delving under the hood of MFC, often you can read between the lines of his narrative and get a sense of the underlying design goals. In the case of message maps, he devotes ten full pages to unraveling the twisted set of macros that implement this peculiar mechanism.
In summary, when you need the answer to a specific programming problem, it's fairly easy to sacrifice principles of elegance and conciseness. The Kruglinski, Blaszczak, and Brain/Lovette books contain plenty of answers (the Brain/Lovette book comes with an online index, not just a listings diskette). Any one of them would be a worthwhile addition to your library. Ironically, my particular question turned out not be found in any of these books, and I had to rely on the "tribal knowledge" of a friend to solve the CPropertySheet problem.
Mastering Object-Oriented Design in C++
Cay S. Horstmann
John Wiley, 1995, 454 pp., $43.95
ISBN 0-471-59484-9
Inside Visual C++, Second Edition
David Kruglinksi
Microsoft Press, 1994, 768 pp., $39.95
ISBN 1-55615-661-8
Visual C++ How-To
Scott Stanfield, Mickey Williams, Alan Light, and Ralph Arvesen
Waite Group Press, 1995
570 pp., $39.95
ISBN 1-878739-82-4
Win32 Programming using Visual C++
Mike Blaszczak
Wrox Press, 1995, 733 pp., $44.95
ISBN 1-874416-47-8
Visual C++ 2
Marshall Brain and Lance Lovette
Prentice Hall, 1995
834 pp., $42.95
ISBN 0-13-305145-5
Development Library CD-ROM
Microsoft Developer Network
$195 for 4-issue subscription
http://www.microsoft.com/msdn/
Copyright © 1995, Dr. Dobb's Journal