Book Reviews


Advanced C++

reviewed by Nimish R. Doshi


Nimish Doshi is an experienced software engineer currently developing graphical user interfaces in New Jersey. He has an M.S. in computer science and his computer interests include object-oriented technology and distributed applications. He can be reached via e-mail at ej798@cleveland.Freenet.Edu.

Introduction

When I first picked up Advanced C++, by Namir Clement Shammas, I was an intermediate C++ developer whose first book on the subject was A1 Steven's Teach Yourself C++. This first book served as a nice tutorial, but left me hungry for more information on how to take advantage of C++'s many rich capabilities. That is why I turned to Advanced C++. Snammas's title is somewhat of a misnomer, since his book is as much about object-oriented programming and data structures as it is about advanced C++. The book is divided into three parts, with two-thirds of the material dedicated to data structures modeled as C++ classes. This pleasantly provided me much more information than I was prepared to grasp!

The title implies that the book is intended for readers with at least a working knowledge of C++. Shammas does not assume his readers are experts however. The book is also accessible (an important feature for this kind of book, whether you're an expert or not) thanks to Shammas's clear writing style and abundant code examples. The examples are annotated with discussions that account for alternative ways of implementation. All examples are also included on an MS-DOS formatted disk, which accompanies the book. These examples will compile with an IBM-PC-compatible C++ compiler (e.g. Borland). The book's length (784 pages) may seem intimidating to some, but needlessly so. The extra length merely serves the book's purpose to make the C++ programmer proficient. I must say that the book fulfills its purpose very well.

Advanced Components of C++

Shammas opens up the first twelve chapters with advanced issues of C++. The chapters serve as an advanced tutorial rather than a plethora of tricks of the language.

Shammas first reviews reference parameters, default arguments, overloading, and template functions. He encourages the use of default parameters to avoid excessive overloading of functions, with their multiplicity of signatures. The template function is the key to eliminating repetitious code, as it allows the same function to handle a variety of data types. Most template functions perform some kind of relational comparison. Shammas reminds us to always provide relational operators for those classes which are used as actual data types for template functions. He provides a simple example of a template function which swaps two reference parameters:

template<class T>
void swap(T& i, T& j)
{
   T temp = i;
   i = j;
   j = temp;
}
He then goes on to discuss the various roles of member functions, such as auxiliary roles and access roles. Another role he describes is that played by dormant member functions. A dormant member function is one that can be either active or inactive (i.e., do what it's designed to do, or do nothing) for different instantiated objects of the same type. C++ provides no built-in mechanism to make individual member functions turn themselves on or off. One way to add this feature to a class is to include a private integer member in the class definition that keeps track of a member function's activation state. The class's constructor initializes this integer, which is then updated when different actions take place upon the object. Depending on the integer's value, functions can either remain dormant or become active. Dormant member functions provide a finer granularity in manipulating objects of the same class.

In this first portion of the book Shammas covers a variety of other topics, including purposes of static members, a survey of all the C++ operators (including a handy example of how the () operator can be used to do almost anything), the overloading of new and delete operators, nested declarations, template classes, and exception handling.

Exception handling deserves further mention in this report, since it is one of the newest components of the language, modeled after Ada's approach. The example in this book illustrates how exception handling can be used to "catch" an out-of-bounds condition for an array class. The syntax of exception handling is

try { // statements to try to execute
}
catch(exception) { // statements attempting to deal with
                   // exception }
When any statement inside the try block reaches a predefined error condition, that statement will raise an exception by using the keyword throw followed by the exception type. The catch statement will respond to the error condition. In Shammas's examples, the catch statement simply prints a message to cout and exits.

Object Oriented Programming

The next part of the book provides numerous examples of inheritance, ranging from shapes to n-dimensional objects such as matrices. The best section here is the discussion on object behavior. Shammas keeps things interesting by demonstrating real-world behavior of objects, with examples from several realms.

Many people see objects as mere state holders, with the private members representing the state of the object. However, an object is semantically more than just a bunch of combinatorial Boolean values. For instance, Shammas ably demonstrates this with an example of an object representing a plane and its engines. Depending on what messages are passed to the object and its internal state (e.g. fuel supply), the object's "flying behavior" will change. When all four of its engines fail, the object invokes a private method called shutdown. This action effectively disables the object, modeling semantically what would happen in the real world. (Of course, in the real world, the plane would probably make an emergency landing.)

Another, more scientific example is that of objects representing chemical elements and molecules. When two elements, such as hydrogen and oxygen, chemically react, a portion of one element usually remains which was not involved in the reaction. Modeling this reaction with Boolean values will not work. One way that will work is to give these objects weights. When a function is used to simulate the chemical reactions, the weights change as one object is completely used up while the residue of another remains. This is Shammas's concept of a transformed object. The capacity of an object to undergo a metamorphosis is what gives it real-world behavior. Shammas elegantly illustrates this point in the book.

Class Templates

Shammas's brief treatment of object behavior is a sidetrack to the main part of his book. The main part deals with data structures — represented by C++ classes holding template data. As I have not dealt with some of these structures since my sophomore year in college, I found this an interesting review. The data structures covered in this book are

Each chapter introduces the properties of the data structure and then provides a possible implementation. All of the container data structures, such as lists, are modeled as template classes. One of the most exotic data structures presented is an internal hash table which uses AVL trees as entries to speed up searches during collisions. (An AVL tree is a height-balanced binary tree of sorted data entries.)

Advanced C++ serves as a perfect model for anyone who is interested in creating a template class library for reusable data structures. A lot of people simply don't use many of the data structures they spent so much time studying in school. That's because many of the structures are tedious to implement and must be reimplemented for various data types. The real boon of template classes is that once they are created, they prove to be quite reusable with little or no modification. Generality is the programmer's dream come true for avoiding repetitious coding. In Shammas's examples, most of the class members are protected, implying that inheritance is the way to enhance the behavior of the class. I think Shammas does an excellent job in presenting his template classes and associated member functions. The only thing I don't like is that the examples utilizing the template data structures are too mundane and simple. I think it would have been more interesting if Shammas had combined real-world object behavior with the template data structures.

Still Hungry

As I said before, when I first picked up, Advanced C++, I did not expect such an extensive treatment of data structures. I almost think the title of the book should have been Advanced C++ and C++ Data Structures. If Shammas overemphasizes one topic, it seems to be at the expense of a few others — for example, polymorphism, inheritance, and memory management.

Some would say that polymorphism — the ability of pointers, references, and member functions to take on new behaviors in derived data types at run time — is the foundation of object-oriented programming. Certainly, it is an important topic as it relates to C++. Yet Shammas does not deal with polymorphism in any great detail. This is in contrast to some books which devote much of their space to lengthy discussions of virtual functions. It may be that with the addition of templates, the need for polymorphism in C++ to simulate genericity may diminish. Nonetheless, I believe any discussion of advanced C++ issues should cover this topic extensively.

Another omission — of which almost all C++ books are guilty — is a discussion on when to use multiple inheritance. This book is no exception, as it presents few good examples of this concept. Of course, some Smalltalk purists will say that it is never good practice to engage in multiple inheritance. However, there are times when multiple inheritance may actually model real-world behavior very well. For instance, in Bertrand Meyer's famous book, Object Oriented Software Construction, he mentions a class of drivers which are American and French. It makes sense for this class of drivers to inherit from both the American and French classes. Perhaps multiple inheritance leads to more complex implementations, but that does not mean programmers should avoid it in all cases. We need some good examples.

Finally, in today's programming environment, object-oriented programming often leads to memory leaks, as this type of development usually necessitates the need to allocate memory for dynamic objects. Sometimes developers become careless and inadvertently forget to free up the space for the object once it is no longer needed. Although Advanced C++ is not a book about the pitfalls of C++, I would have liked to have seen more mention of this critical issue.

A Good Teacher

Shammas is a good teacher. Like all good teachers, he has organized his course well, first presenting advanced language components and then laying out class templates for data structures. (In keeping with this approach, he presents the most difficult data structure, the B-tree, last.)

This is not a cookbook. Programmers looking for the proverbial 1,001 C++ tricks will not find them here. Rather, I recommend this book for the intermediate C++ user because it is a very readable tutorial and can serve as reference for various topics. Most of the examples in the book are generic enough to be slightly modified to work under any modern C++ compiler. Shammas, an accomplished author, has provided the C++ user community a service by writing this book.

Title: Advanced C++
Author: Namir Clement Shammas
Publisher: SAMS Publishing
Pages: 784
Price: $39.95
ISBN: 0-672-30158-X