Title: Secrets of the C++ Masters
Author: Jeff Alger
Publisher: Academic Press
Release: 1995, First edition
Pages: 381
Price: $39.95
ISBN: 0-12-049940-1
Near the beginning of Secrets of the C++ Masters, Jeff Alger describes three stages of learning C++, likening the process to an elevator ride. His description reminds me of my own experience:
In the first stage, I learned about cute things like classes, inheritance, polymorphism, virtual functions, and many others people still enumerate when you ask them "Gimme five words you have in mind when you think about C++?"
In the second stage, I started to build class libraries, I built a set of container classes with iterators, a math and value library, a library for IPC, and when I finally mastered writing perfectly homomorphic container class libraries they came along with templates and STL.
What might be next? The final stage, according to Alger, is to discover that C++ is not so much a language as a way of creating your own languages. Alger claims that this property enables C++ to solve problems as elegantly as "a real language like Smalltalk or Lisp ..., but without causing smoke to rise from your CPU ..." Well, the statement that C++ is not a real language concerns me, even if its intent may be to raise C++ up as something more than a language. Personally, I think C++ is not better or worse than other languages, it's just a fine-grained language with many facets. You may use C++ as a better assembler. You may also use C++ as a real language with many added features, such as garbage collection -- the difference being that garbage collection is optional in C++, since it is not part of the language.
Having gone through my own evolution as a C++ programmer, I was very curious to know how the masters do C++ programming. This book claims to be for the intermediate and advanced C++ programmer, bridging the gap between C++ as described in beginner and intermediate-level books and C++ as practiced by "experts." Therefore, the layout of the book is of some interest. How does it go about bridging the gap? The author divides the book into four sections, each new one building on the preceding, extending or combining previous patterns. Along the way the book presents a lot of ideas, too many to enumerate here, so I will shortly summarize the highlights of each section.
The first section, surprisingly enough, is a summary of language features, such as variables and constants, functions, scopes, and even classes. This summary takes over 50 pages compared to only about 20 pages for templates and exception handling. Even more surprising, Alger dedicates a section to the overloading of operator(). Evidently, he thinks we've either forgotten or never learned that operator() can be overloadeed. As justification for including this section, he says "even experienced C++ programmers often have gaps in their background." Indeed, some language features are worth reviewing, but in the overall context of a book for really advanced C++ programmers, I would have appreciated in-depth coverage of more advanced topics.
Section two explains in detail a wide range of pointer classes, including dumb and smart pointers, master pointers, and handles. These all fall into the category of simple pointer classes, which basically replace the C++ pointer in a more or less controlled manner. These simple pointer classes allow easier implementation of debugging code. They also enable object reference counting without changing the classes whose objects are reference counted.
After familiarizing us with these simple pointer types, Alger investigates possible extensions such as "facets" -- which allow the same object to be accessed through different interfaces, proxy objects, and functors. Before moving to pointer types for transaction management and undoable operations, Alger spends some time covering containers and their companion classes, iterator and cursor.
The third section is entitled "Tips on Types," which explains, among other things, double- and multiple-dispatch, and factory functions and how to localize them. This section also introduces the notion of the Class class, which provides detailed knowledge about objects of that class. The second part of this section revisits pointer classes and introduces the invisible pointer, yet another pointer type.
The last section explains ways to do memory management. Alger explains various techniques for customized memory management, such as memory pools, reference counting and its problems, and memory spaces. A large part of the section discusses how to do memory compaction, pointer enumeration, and Baker's Algorithm. The closing chapter introduces the "scavenging" technique.
Since Secrets of the C++ Masters is a book for C++ programmers, Alger provides all examples in the form of source code. There are many code fragments focusing on important points of the discussed classes. The diskette accompanying the book contains about 83Kb of code. Alger strictly avoids any graphic representation of the patterns he develops. People who are accustomed to seeing class relationships and interactions in some OO notation would probably appreciate the presence of such diagrams. However, Alger might argue that his book is for practical C++ programming, not for teaching generalized OOD, and he would be right. How many different ways must an author show how to implement the "has-by-reference" relationship between two classes?
Gaps in the Background
I didn't expect an entire section explaining basics in a book for experts, but I did expect at least one entire section explaining templates and exception handling in depth. Should we conclude that masters don't throw exceptions? I also expected the author to have a deep knowledge of the language, at least deep enough to know that built-in types such as int do not have constructors and a destructor (pages 19-20)! And I must also point out a few things about the quality of Alger's code. Alger implements the overloaded operator+ for the String class as follows (this global operator is defined as friend of the String class):
String operator+(const String& s1, const String& s2) { char* s = new char[strlen(s1.s)+strlen(s2.s)+1]; strcat(s, s1.s, s2.s); String newStr(s); delete s; return newStr; }Even if this example is not intended as production code, I don't understand why someone would use such a bad example in a textbook for "masters." If you use this piece of code as is, you may run into trouble: s is allocated with array new but freed with delete instead of delete[]. I admit that, as I stated before, built-in types do not have destructors, so calling the delete operator on each object in the array is not important here. But this code is sloppy. I have already spent some hours troubleshooting sporadic coredumps in my own code caused by exactly this type of flaw. A programmer should generally avoid such errors, especially if he is a master. Perhaps, to be fair, it was just a typo?
I also wonder why we find a beginner-style implementation of the well-known String::operator+ in an expert book. First operator+ allocates a temporary char array, then hands it to the String constructor that, no doubt, will make its own copy elsewhere, and finally the temporary char array is destroyed. Welcome to fragmentation of memory! Nowhere did I find -- and this is one of the things, in my opinion, that makes a master -- a word about efficient management of temporary memory.
Alger shows how to address a multidimensional array with a special Index class, as follows:
String s = anArray[Index(17, 29, 31)];A true masterpiece would enable access with
String s = anArray[17][29][31];I suppose (and hope) that the paragraph entitled "Templates are Glorified Macros" (page 72) is due to the fact that most compilers had very weak or no template support when the book was written. I am curious to know if Alger could rewrite STL using preprocessor macros.
Some of the hardest code I've ever had to write dealt with transaction management and multilevel undo, with relationships existing between objects residing in different databases. I hoped that Secrets of the C++ Masters would help me out here. Unfortunately, it did not. Sure, the various image pointers Alger illustrates throughout that chapter are helpful, but I need to see the framework they fit in. Saving one or multiple backup copies transparently is a good thing to demonstrate, but the transaction control mechanism is a crucial as well -- and missing.
Saving Graces
In spite of the deficiencies I have outlined (and they are not the only ones) I consider Secrets of the C++ Masters to be a useful collection of advanced C++ programming patterns. I would not say that its title was a good choice. Some C++ background and also some OOD knowledge will help readers convert Alger's code fragments to something (re)usable. He presents good base implementations for a wide variety of pointers, enough to cover almost any conceivable task. He provides a good overview of types and class hierarchies, containers and their companions, and last but not least global memory management.
A book that tries to discuss that many different aspects of programming cannot cover each one in depth. The book succeeded in providing a good overview of many C++ programming techniques. It also makes for funny reading (intentionally) and most of the time is easy to understand. I am sure that the next edition will clean up some code flaws and update the chapters concerning templates and exception handling to be more accurate. I would classify Secrets of the C++ Masters a "should-have" book, nevertheless one I won't likely miss, considering the many others on my bookshelf. o
Marc Kilian is a self-taught programmer and a software engineer at ACOSOFT S.A. in Switzerland. He is writing a database engine for a 3-D modeling system that models metallic profiles of buildings. Marc's interests include object technology, and he notes that he "will not reject offers" as a consultant in this field. He can be reached at marc.kilian@nethos.net.