Thinking in C++ - Volume 2
Thinking in C++ - Volume 2
Date de publication : 25/01/2007 , Date de mise à jour : 25/01/2007
0. Introduction
0.1. Goals
0.2. Chapters
0.3. Exercises
0.3.1. Exercise solutions
0.4. Source code
0.5. Compilers
0.6. Language standards
0.7. Seminars, CD–ROMs & consulting
0.8. Errors
0.9. About the cover
0.10. Acknowledgements
0. Introduction
In Volume 1 of this book, you learned the fundamentals of C and
C++. In this volume, we look at more advanced features, with an eye towards
developing techniques and ideas that produce robust C++ programs.
We assume you are familiar with the material presented in
Volume 1.
0.1. Goals
Our goals in this book are to:
- Present the material a simple step at a time, so the reader can easily digest each concept before moving on.
- Teach “practical programming” techniques that you can use on a day-to-day basis.
- Give you what we think is important for you to understand about the language, rather than everything we know. We believe there is an “information importance hierarchy,” and there are some facts that 95% of programmers will never need to know, but that would just confuse people and add to their perception of the complexity of the language. To take an example from C, if you memorize the operator precedence table (we never did) you can write clever code. But if you must think about it, it will confuse the reader/maintainer of that code. So forget about precedence and use parentheses when things aren't clear. This same attitude will be taken with some information in the C++ language, which is more important for compiler writers than for programmers.
- Keep each section focused enough so the lecture time—and the time between exercise periods—is small. Not only does this keep the audience' minds more active and involved during a hands-on seminar, but it gives the reader a greater sense of accomplishment.
- We have endeavored not to use any particular vendor's version of C++. We have tested the code on all the implementations we could (described later in this introduction), and when one implementation absolutely refused to work because it doesn't conform to the C++ Standard, we've flagged that fact in the example (you'll see the flags in the source code) to exclude it from the build process.
- Automate the compiling and testing of the code in the book. We have discovered that code that isn't compiled and tested is probably broken, so in this volume we've instrumented the examples with test code. In addition, the code that you can download from http://www.MindView.net has been extracted directly from the text of the book using programs that automatically create makefiles to compile and run the tests. This way we know that the code in the book is correct.
0.2. Chapters
Here is a brief description of the chapters contained in
this book:
Part 1: Building Stable Systems
1. Exception handling. Error handling has always been
a problem in programming. Even if you dutifully return error information or set
a flag, the function caller may simply ignore it. Exception handling is a
primary feature in C++ that solves this problem by allowing you to “throw” an
object out of your function when a critical error happens. You throw different
types of objects for different errors, and the function caller “catches” these
objects in separate error handling routines. If you throw an exception, it
cannot be ignored, so you can guarantee that something will happen in
response to your error. The decision to use exceptions affects code design in positive,
fundamental ways.
2. Defensive Programming. Many software problems can
be prevented. To program defensively is to craft code in such a way that bugs are
found and fixed early before they can damage in the field. Using assertions is
the single most important way to validate your code during development, while
at the same time leaving an executable documentation trail in your code that
reveals your thoughts while you wrote the code in the first place. Rigorously
test your code before you let out of your hands. An automated unit testing framework
is an indispensable tool for successful, everyday software development.
Part 2: The Standard C++ Library
3. Strings in Depth. The most common programming
activity is text processing. The C++ string class relieves the programmer from
memory management issues, while at the same time delivering a powerhouse of
text processing capability. C++ also supports the use of wide characters and
locales for internationalized applications.
4. Iostreams. One of the original C++ libraries—the
one that provides the essential I/O facility—is called iostreams. Iostreams is
intended to replace C's stdio.h with an I/O library that is easier to
use, more flexible, and extensible—you can adapt it to work with your new
classes. This chapter teaches you how to make the best use of the existing
iostream library for standard I/O, file I/O, and in-memory formatting.
5. Templates in Depth. The distinguishing feature of
“modern C++” is the broad power of templates. Templates do more than just create
generic containers. They support development of robust, generic,
high-performance libraries. There is a lot to know about templates—they
constitute, as it were, a sub-language within the C++ language, and give the
programmer an impressive degree of control over the compilation process. It is
not an overstatement to say that templates have revolutionized C++ programming.
6. Generic Algorithms. Algorithms are at the
core of computing, and C++, through its template facility, supports an
impressive entourage of powerful, efficient, and easy-to-use generic
algorithms. The standard algorithms are also customizable through function
objects. This chapter looks at every algorithm in the library. (Chapters 6 and
7 cover that portion of the Standard C++ library commonly known as the Standard
Template Library, or STL.)
7. Generic Containers & Iterators. C++
supports all the common data structures in a type-safe manner. You never need
to worry about what such a container holds. The homogeneity of its objects is
guaranteed. Separating the traversing of a container from the container itself,
another accomplishment of templates, is made possible through iterators. This
ingenious arrangement allows a flexible application of algorithms to containers
using the simplest of designs.
Part 3: Special Topics
8. Runtime type identification.Runtime type
identification (RTTI) finds the exact type of an object when you only have a
pointer or reference to the base type. Normally, you'll want to intentionally
ignore the exact type of an object and let the virtual function mechanism
implement the correct behavior for that type. But occasionally (like when
writing software tools such as debuggers) it is helpful to know the exact type
of an object—with this information, you can often perform a special-case
operation more efficiently. This chapter explains what RTTI is for and how to
use it.
9. Multiple inheritance. This sounds simple at first:
A new class is inherited from more than one existing class. However, you can
end up with ambiguities and multiple copies of base-class objects. That problem
is solved with virtual base classes, but the bigger issue remains: When do you
use it? Multiple inheritance is only essential when you need to manipulate an
object through more than one common base class. This chapter explains the
syntax for multiple inheritance and shows alternative approaches—in particular,
how templates solve one typical problem. Using multiple inheritance to repair a
“damaged” class interface is demonstrated as a valuable use of this feature.
10. Design Patterns. The most revolutionary advance
in programming since objects is the introduction of design patterns. A
design pattern is a language-independent codification of a solution to a common
programming problem, expressed in such a way that it can apply to many
contexts. Patterns such as Singleton, Factory Method, and Visitor now find
their way into daily discussions around the keyboard. This chapter shows how to
implement and use some of the more useful design patterns in C++.
11. Concurrent Programming. People have come to
expect responsive user interfaces that (seem to) process multiple tasks
simultaneously. Modern operating systems allow processes to have multiple
threads that share the process address space. Multithreaded programming
requires a different mindset, however, and comes with its own set of difficulties.
This chapter uses a freely available library (the ZThread library by Eric
Crahen of IBM) to show how to effectively manage multithreaded applications in
C++.
0.3. Exercises
We have discovered that simple exercises are exceptionally
useful during a seminar to complete a student's understanding. You'll find a
set at the end of each chapter.
These are fairly simple, so they can be finished in a
reasonable amount of time in a classroom situation while the instructor
observes, making sure all the students are absorbing the material. Some
exercises are a bit more challenging to keep advanced students entertained.
They're all designed to be solved in a short time and are only there to test
and polish your knowledge rather than present major challenges (presumably,
you'll find those on your own—or more likely they'll find you).
0.3.1. Exercise solutions
Solutions to exercises can be found in the electronic
document The C++ Annotated Solution Guide, Volume 2, available for a nominal
fee from http://www.MindView.net.
0.4. Source code
The source code for this book is copyrighted freeware,
distributed via the web site http://www.MindView.net. The copyright prevents
you from republishing the code in print media without permission.
In the starting directory where you unpack the code you will
find the following copyright notice:
|
You may use the code in your projects and in the classroom
as long as the copyright notice is retained.
0.5. Compilers
Your compiler may not support all the features discussed in
this book, especially if you don't have the newest version of your compiler.
Implementing a language like C++ is a Herculean task, and you can expect that
the features will appear in pieces rather than all at once. But if you attempt
one of the examples in the book and get a lot of errors from the compiler, it's
not necessarily a bug in the code or the compiler—it may simply not be
implemented in your particular compiler yet.
We used a number of compilers to test the code in this book,
in an attempt to ensure that our code conforms to the C++ Standard and will
work with as many compilers as possible. Unfortunately, not all compilers
conform to the C++ Standard, and so we have a way of excluding certain files
from building with those compilers. These exclusions are reflected in the
makefiles automatically created for the package of code for this book that you
can download from www.MindView.net. You can see the exclusion tags embedded in
the comments at the beginning of each listing, so you will know whether to
expect a particular compiler to work on that code (in a few cases, the compiler
will actually compile the code but the execution behavior is wrong, and we
exclude those as well).
Here are the tags and the compilers that they exclude from
the build:
- {-dmc} Walter Bright's Digital Mars compiler for Windows, freely downloadable at www.DigitalMars.com. This compiler is very conformant and so you will see almost none of these tags throughout the book.
- {-g++} The free Gnu C++ 3.3.1, which comes pre-installed in most Linux packages and Macintosh OSX. It is also part of Cygwin for Windows (see below). It is available for most other platforms from gcc.gnu.org.
- {-msc} Microsoft Version 7 with Visual C++ .NET (only comes with Visual Studio .NET; not freely downloadable).
- {-bor} Borland C++ Version 6 (not the free download; this one is more up to date).
- {-edg} Edison Design Group (EDG) C++. This is the benchmark compiler for standards conformance. This tag occurs only because of library issues, and because we were using a complimentary copy of the EDG front end with a complimentary library implementation from Dinkumware, Ltd. No compile errors occurred because of the compiler alone.
- {-mwcc} Metrowerks Code Warrior for Macintosh OS X. Note that OS X comes with Gnu C++ pre-installed, as well.
If you download and unpack the code package for this book
from www.MindView.net, you'll find the makefiles to build the code for the
above compilers. We used the freely-available GNU-make, which comes with
Linux, Cygwin (a free Unix shell that runs on top of Windows; see
www.Cygwin.com), or can be installed on your platform—see
www.gnu.org/software/make. (Other makes may or may not work with these
files, but are not supported.) Once you install make, if you type make
at the command line you'll get instructions on how to build the book's code for
the above compilers.
Note that the placement of these tags on the files in this
book indicates the state of the particular version of the compiler at the time
we tried it. It's possible and likely that the compiler vendor has improved the
compiler since the publication of this book. It's also possible that while
building the book with so many compilers, we may have misconfigured a
particular compiler that would otherwise have compiled the code correctly. Thus,
you should try the code yourself on your compiler, and also check the code
downloaded from www.MindView.net to see what is current.
0.6. Language standards
Throughout this book, when referring to conformance to the
ANSI/ISO C standard, we will be referring to the 1989 standard, and will
generally just say ‘C.' Only if it is necessary to distinguish between
Standard 1989 C and older, pre-Standard versions of C will we make the
distinction. We do not reference C99 in this book.
The ANSI/ISO C++ Committee long ago finished working on the first C++ Standard, commonly known as C++98. We will use the term Standard
C++ to refer to this standardized language. If we simply refer to C++,
assume we mean “Standard C++.” The C++ Standards Committee continues to address
issues important to the C++ community that will become C++0x, a future C++
Standard not likely to be available for many years.
0.7. Seminars, CD–ROMs & consulting
Bruce Eckel's company, MindView, Inc., provides public
hands-on training seminars based on the material in this book, and also for
advanced topics. Selected material from each chapter represents a lesson, which
is followed by a monitored exercise period so each student receives personal
attention. We also provide on-site training, consulting, mentoring, and design
& code walkthroughs. Information and sign-up forms for upcoming seminars
and other contact information is found at http://www.MindView.net.
0.8. Errors
No matter how many tricks writers use to detect errors, some
always creep in and these often leap off the page for a fresh reader. If you
discover anything you believe to be an error, please use the feedback system
built into the electronic version of this book, which you will find at http://www.MindView.net.
Your help is appreciated.
0.9. About the cover
The cover artwork was painted by Larry O'Brien's wife, Tina
Jensen (yes, the Larry O'Brien who was the editor of Software Development
Magazine for so many years). Not only are the pictures beautiful, they are also
excellent suggestions of polymorphism. The idea for using these images came
from Daniel Will-Harris, the cover designer (www.Will-Harris.com), working with
Bruce.
0.10. Acknowledgements
Volume 2 of this book languished in a half-completed state
for a long time while Bruce got distracted with other things, notably Java,
Design Patterns and especially Python (see www.Python.org). If Chuck hadn't
been willing (foolishly, he has sometimes thought) to finish the other half and
bring things up-to-date, this book almost certainly wouldn't have happened.
There aren't that many people whom Bruce would have felt comfortable entrusting
this book to. Chuck's penchant for precision, correctness and clear explanation
is what has made this book as good as it is.
Jamie King acted as an intern under Chuck's direction during
the completion of this book. He was an essential part of making sure the book
got finished, not only by providing feedback for Chuck, but especially because
of his relentless questioning and picking of every single possible nit that he
didn't completely understand. If your questions are answered by this book, it's
probably because Jamie asked them first. Jamie also enhanced a number of the
sample programs and created many of the exercises at the end of each chapter.
Scott Baker, another of Chuck's interns funded by MindView, Inc., helped with
the exercises for Chapter 3.
Eric Crahen of IBM was instrumental in the completion of
Chapter 11 (Concurrency). When we were looking for a threads package, we sought
out one that was intuitive and easy to use, while being sufficiently robust to
do the job. With Eric we got that and then some—he was extremely cooperative
and has used our feedback to enhance his library, while we have benefited from
his insights as well.
We are grateful to Pete Becker for being our technical
editor. Few people are as articulate and discriminating as Pete, not to mention
as expert in C++ and software development in general. We also thank Bjorn
Karlsson for his gracious and timely technical assistance as he reviewed the
entire manuscript with short notice.
Walter Bright made Herculean efforts to make sure that his
Digital Mars C++ compiler would compile the examples in this book. He makes the
compiler available for free downloads at http://www.DigitalMars.com. Thanks, Walter!
The ideas and understanding in this book have come from many
other sources, as well: friends like Andrea Provaglio, Dan Saks, Scott Meyers,
Charles Petzold, and Michael Wilk; pioneers of the language like Bjarne
Stroustrup, Andrew Koenig, and Rob Murray; members of the C++ Standards
Committee like Nathan Myers (who was particularly helpful and generous with his
insights), Herb Sutter, PJ Plauger, Kevlin Henney, David Abrahams, Tom Plum,
Reg Charney, Tom Penello, Sam Druker, Uwe Steinmueller, John Spicer, Steve
Adamczyk, and Daveed Vandevoorde; people who have spoken in the C++ track at
the Software Development Conference (which Bruce created and developed, and
Chuck spoke in); Colleagues of Chuck like Michael Seaver, Huston Franklin,
David Wagstaff, and often students in seminars, who ask the questions we need
to hear to make the material clearer.
The book design, typeface selection, cover design, and cover
photo were created by Bruce's friend Daniel Will-Harris, noted author and
designer, who used to play with rub-on letters in junior high school while he
awaited the invention of computers and desktop publishing. However, we produced
the camera-ready pages ourselves, so the typesetting errors are ours. Microsoft®
Word XP was used to write the book and to create camera-ready pages. The body
typeface is Verdana and the headlines are in Verdana. The code type face is
Courier New.
We also wish to thank the
generous professionals at the Edison Design Group and Dinkumware, Ltd., for
giving us complimentary copies of their compiler and library (respectively).
Without their expert assistance, graciously given, some of the examples in this
book could not have been tested. We also wish to thank Howard Hinnant and the
folks at Metrowerks for a copy of their compiler, and Sandy Smith and the folks
at SlickEdit for keeping Chuck supplied with a world-class editing environment
for so many years. Greg Comeau also provided a copy of his successful EDG-based
compiler, Comeau C++.
A special thanks to all
our teachers, and all our students (who are our teachers as well).
Evan Cofsky
(Evan@TheUnixMan.com) provided all sorts of assistance on the server as well as
development of programs in his now-favorite language, Python. Sharlynn Cobaugh
and Paula Steuer were instrumental assistants, preventing Bruce from being
washed away in a flood of projects.
Bruce's sweetie Dawn McGee provided much-appreciated
inspiration and enthusiasm during this project. The supporting cast of friends
includes, but is not limited to: Mark Western, Gen Kiyooka, Kraig Brockschmidt,
Zack Urlocker, Andrew Binstock, Neil Rubenking, Steve Sinofsky, JD Hildebrandt,
Brian McElhinney, Brinkley Barr, Bill Gates at Midnight Engineering Magazine,
Larry Constantine & Lucy Lockwood, Tom Keffer, Greg Perry, Dan Putterman,
Christi Westphal, Gene Wang, Dave Mayer, David Intersimone, Claire Sawyers, The
Italians (Andrea Provaglio, Laura Fallai, Marco Cantu, Corrado, Ilsa and
Christina Giustozzi), Chris & Laura Strand, The Almquists, Brad Jerbic,
John Kruth & Marilyn Cvitanic, Holly Payne (yes, the famous novelist!),
Mark Mabry, The Robbins Families, The Moelter Families (& the McMillans),
The Wilks, Dave Stoner, Laurie Adams, The Cranstons, Larry Fogg, Mike &
Karen Sequeira, Gary Entsminger & Allison Brody, Chester Andersen, Joe
Lordi, Dave & Brenda Bartlett, The Rentschlers, The Sudeks, Lynn &
Todd, and their families. And of course, Mom & Dad, Sandy, James &
Natalie, Kim& Jared, Isaac, and Abbi.