Errata for "Thinking in C++" first printing. Note that code listings
corrections have been made in this code distribution, and corrections
have been made in the second printing. Thanks to all the readers that
sent in the corrections.

-- Extra quote mark on back cover after PJ Plauger (not corrected)
-- Copyright page: Daniel Will-Harris' email should be:
   daniel@will-harris.com
-- Page numbering errors in table of contents (see end of this document)
-- Page 24: 6th line:
   (12) Composition & inheritance ...
   should be:
   (12) Inheritance and composition ...
-- Page 24: 15th line: should be
   (13) Polymorphism & virtual functions
-- Page 26, under heading "Source Code", second sentence should read:

   You should be able to find it on many bulletin board systems (such
   as CompuServe and AOL), Internet nodes (Such as the SimTel archives;
   oak.oakland.edu is one node; see SimTel/msdos/cpluspls), and included
   in product vendor packages. 

-- Page 28: Zip code for EckelBits should be 91941-4259
-- Page 30: under "seminars & mentoring," misplaced comma, should be
   right after "on"
-- Page 32: 16th line end, should be John H. Carson, not John C. Carson
-- Page 54, third line: "(Not coincidentally, this is what you do with
   OOP.)" should read "(This is what you do, not coincidentally, with OOP.)"
-- Page 58, 7th line up from the bottom, should read: "You can view ..."
-- Page 83, 12th line up from the bottom, should read:
   "first for speedups that can be done ..."
-- Page 102, under heading "file names", 7th line down, should read:
   "file names. The original ..."
-- Page 109, last paragraph on page, second line down, should read:
   "C++ is to compile ..."
-- Page 122, code listing, fourth & third lines from end of listing, 
   should read:
   while((s = (char*)textlines.pop()) != 0) {
     printf("%s", s); free(s); }
-- Page 180, 4th line above heading "overloading example", should be:
   often, when it does it can be incredibly difficult to find, especially in 
-- Page 188, code listing, top two lines should read:
   for(int j = 0; j < fl.size(); j++)
     printf("fl.read(%d)= %d\n", j, fl.read(j));
-- Page 195, code listing, 16 lines down from start of listing:
   for(int j=bv2.bits()-10; j<bv2.bits(); j++)
     bv2.clear(j);
-- Page 223, 2nd line after listing: "tmp.tmp" should be "iofile.out"
-- Page 225, Replace the paragraph portion:

   Because the compiler handles the static storage allocation of the
   string buf points to, the same result could have been accomplished 
   with
   istrstream s("47 1.414 This is a test");
   In either case, s ends up working with a zero-terminated string. 

   with:

   The compiler handles the static storage allocation of the string in
   istrstream s("1.414 47 This is a test");
   You can also hand it a pointer to a zero-terminated string allocated
   on the stack or the heap.

-- Page 262, code listing, top line should read:
   //: DATALOG.CPP -- Datapoint member functions
-- Page 295, 2nd line down from top code fragment: "an argument of one." 
   should be "an argument of two."
-- Page 315, end of top code listing, the replace the lines reading:

   // Transpose width & height:
   R.height(R.width());
   R.width(R.height());

   with:

   // Change width & height:
   R.height(2 * R.width());
   R.width(2 * R.height());

-- Page 325, Add line to end of page:
   "The solution is to replace the semicolon with a comma in the macro."
-- Page 345, in the code fragments, replace "f()" with "q()" and "g()"
   with "s()".
-- Page 363 : add last exercise from Chapter 9
-- Page 367 - 395, odd pages: footer should read 
   "Chapter 9: References & the Copy-Constructor"
-- Page 396 : Move last exercise to page 363
-- Page 401, starting at 3rd line of listing, 3 lines should read:
   class integer {
     long i;
     integer* This() { return this; }
-- Page 402, function for operator& should be:
   integer* operator&(integer& a) {
     cout << "&integer\n";
     return a.This(); // &a is recursive!
   }
-- Page 403, postfix operator++ and operator-- should be:

   const byte operator++(int) { // Postfix
     cout << "byte++\n";
     byte before(b);
     b++;
     return before;
   }

   and:

   const byte operator--(int) { // Postfix
     cout << "byte--\n";
     byte before(b);
     --b;
     return before;
   }

-- Page 461, 2nd sentence of point 1: replace "is constant" with "exists"
-- Page 473, lines 12-14 of listing should read:
   for(int u = 0; u < intStash.count(); u++)
     cout << "intStash[" << u << "] = "
          << *(int*)intStash[u] << endl;
-- Page 473, lines 29-31 of listing should read:
   for(int v = 0; stringStash[v]; v++) {
     char* p = *(String*)stringStash[v];
     cout << "stringStash[" << v << "] = "
-- Page 523, 1st paragraph below heading "multiple inheritance", fourth
   line down, remove the word "use" at the end of the line.
-- Page 550: footnote 2, the second "C++" should be "C"
-- Page 561: The function "call" should read:
   void call(base b) {
-- Page 575, bottom listing line on page, replace line with:
   int i;
   for(i = 0; i < sz; i++)
-- Page 576, 5th line up from bottom of listing, replace lines with:
   for(int j = 0; j < 20; j++)
     cout << it++ << endl;
   for(int k = 0; k < 20; k++)
     cout << is.pop() << endl;
-- Page 582, fourth line down, remove the phrase:
   "instead of templates for parameterized types,"
-- Page 584, 8th line down from top listing, replace 3 lines with:
   for(int j = 0; j < 20; j++)
     cout << j << ": " << ia[j]
          << ", " << fa[j] << endl;
-- Page 586, 4th line down from start of listing STACKT.H, insert the
   line:
   template<class T> class stacktIter; // declare
-- Page 588, 13 lines down from the top of the code listing, replace
   line with:
   int i;
   for(i = 0; i < sz; i++)
-- Page 588, two lines up from bottom, replace line with:
   for(int j = 0; j < 20; j++)
-- Page 589, top line, replace line with:
   for(int k = 0; k < 20; k++)
-- Page 589 - 590, listing MBLOCK.CPP: move definition for class number
   ahead of definition for class holder. (templates now require
   declaration before use).
-- Page 592, listing TSTASH.H, replace lines starting at last #include
   with:
   #include "..\allege.h"
   // More convenient than nesting in tstash:
   enum owns { no = 0, yes = 1, Default };
   // Declaration required:
   template<class Type, int sz> class tstashIter;
-- Page 597, starting 10 lines up from bottom, replace next 5 lines
   with:
   for(int j = 0; j < 20; j++, Intit++)
     Intit.remove(); // Default removal
   for(int k = 0; k < intStash.count(); k++)
     if(intStash[k]) // Remove() causes "holes"
       out << *intStash[k] << endl;
-- Page 598, top listing, replace lines 4-6 with:
   for(int u = 0; u < stringStash.count(); u++)
     if(stringStash[u])
       out << *stringStash[u] << endl;
-- Page 598, 5th line down in TSTACK.H, replace
   "// Some implementations require this:" 
   with
   "// Declaration required:"
-- Page 627: The function "SumValue" should have a void return value
-- Page 641: Code listing GENERATE.CPP, insert at third line:
   #include "..\14\integer.h"
   Then replace all references to "Int2" with "integer"
-- Page 642: Listing SPECIAL.CPP should #include <iostream.h>
-- Page 660: Footnote: "Jan Grey" should be "Jan Gray"
-- Page 693: text line right above bottom code fragment, "(a la C)" should
   have an accent above the "a".
-- Page 697: remove top two lines (they repeat the lines from the previous
   page).
-- Page 702: At top, insert the two lines:
   cleaned up?" Most of the time youre fairly safe, but in constructors 
   theres a problem: If an exception is thrown before a constructor is 
-- Page 702: remove the last two lines on the page.
-- Page 709: First line under header "standard exceptions, remove "that"
-- Page 717: under "don't cause exceptions in destructors," the
   beginning of the third line down, replace "constructor" with "destructor"
-- Page 724: 2nd paragraph down, should read:

   You can also ask a typeinfo object if it precedes another typeinfo 
   object in the implementation-defined "collation sequence," using 
   before(typeinfo&), which returns true or false. When you say,
     if(typeid(me).before(typeid(you))) // ...
   youre asking if me occurs before you in the collation sequence.

-- Page 727: 7 lines up from bottom in code listing. Replace 3 lines
   with:
   for(int j = 0; j < rand() % mod; j++)
     shapes.add(new ellipse);
   for(int k = 0; k < rand() % mod; k++)
-- Page 728: 2nd line down from top in code listing, replace 9 lines
   with:
   for(int u = 0; u < shapes.count(); u++) {
     shapes[u]->draw();
     if(dynamic_cast<circle*>(shapes[u]))
       Ncircles++;
     if(dynamic_cast<ellipse*>(shapes[u]))
       Nellipses++;
     if(dynamic_cast<rectangle*>(shapes[u]))
       Nrects++;
     if(dynamic_cast<shape*>(shapes[u]))
-- Page 752: in the code listing, two lines below class X, the M in
   "mutable" should be lower case
-- Page 758: The first column in the last entry in the table. Replace
   ":?" with "? :"
-- Page 780: At the end of the page, add a last point:

   62. Sometimes simple aggregation does the job. A "passenger 
   comfort system" on an airline consists of disconnected elements:
   seat, air conditioning, video, etc., and yet you need to create 
   many of these in a plane. Do you make private members and build a 
   whole new interface? No -- in this case, the components themselves 
   are also part of the public interface, so you should create public 
   member objects. Those objects have their own private implementations,  
   which are still safe.

-- Page 801: replace "Grey, Jan, 660" with "Gray, Jan, 660"


====================== Corrected table of Contents ===================
The table of contents has errors in the page numbering. Here is the
corrected table of contents:

preface, 15
prerequisites, 16
learning C++, 17
goals, 19
chapters, 20
exercises, 26
source code, 26
coding standards, 28
language standards, 29
language support, 30
seminars & mentoring, 30
errors, 31
acknowledgements, 31

0: the evolution of objects, 35
key concepts, 36
objects: characteristics + behaviors, 36
inheritance: type relationships, 37
polymorphism, 38
manipulating concepts: what an OOP program looks like, 40
why C++ succeeds, 41
a better C, 42
you're already on the learning curve, 42
efficiency, 43
systems are easier to express and understand, 43
maximal leverage with libraries, 44
error handling, 44
programming in the large, 45
introduction to methods, 45
complexity, 46
internal discipline, 47
external discipline, 49
five stages of object design, 55
what a method promises, 57
what a method should deliver, 58
"required" reading, 61
scripting: a minimal method, 63
premises, 64
1. high concept, 67
2. treatment, 68
3. structuring, 69
4. development, 71
5. rewriting, 74
logistics, 75
other methods, 76
Booch, 76
Responsibility-Driven Design (RDD), 78
Object Modeling Technique (OMT), 79
strategies for translation, 80
stepping up to OOP, 80
management obstacles, 82
summary, 84

1: data abstraction, 87
declarations vs. definitions, 89
a tiny C library, 91
dynamic storage allocation, 95
bringing it all together: project-building tools, 101
file names, 102
what's wrong?, 102
the basic object, 104
what's an object?, 112
abstract data typing, 113
object details, 114
header file etiquette, 116
using headers in projects, 118
nested structures, 118
global scope resolution, 122
summary, 123
exercises, 124

2: hiding the implementation, 125
setting limits, 126
C++ access control, 127
protected, 129
friends, 129
nested friends, 132
is it pure?, 135
object layout, 135
the class, 136
modifying stash to use access control, 139
modifying stack to use access control, 140
handle classes, 141
visible implementation, 142
reducing recompilation, 142
summary, 146
exercises, 146

3: initialization & cleanup, 149
guaranteed initialization with the constructor, 151
guaranteed cleanup with the destructor, 153
elimination of the definition block, 156
for loops, 158
storage allocation, 159
stash with constructors and destructors, 161
stack with constructors and destructors, 164
aggregate initialization, 167
default constructors, 170
summary, 172
exercises, 173

4: function overloading & default arguments, 175
more mangling, 177
overloading on return values, 178
type-safe linkage, 179
overloading example, 180
default arguments, 184
a bit vector class, 186
summary, 196
exercises, 198

5: introduction to iostreams, 199
why iostreams?, 200
true wrapping, 202
iostreams to the rescue, 205
sneak preview of operator overloading, 206
inserters and extractors, 207
common usage, 210
line-oriented input, 212
file iostreams, 214
open modes, 217
iostream buffering, 218
using get( ) with a streambuf, 220
seeking in iostreams, 220
creating read/write files, 222
strstreams, 223
user-allocated storage, 224
automatic storage allocation, 228
output stream formatting, 232
internal formatting data, 233
an exhaustive example, 238
formatting manipulators, 242
manipulators with arguments, 243
creating manipulators, 246
effectors, 248
iostream examples, 251
code generation, 251
a simple datalogger, 261
summary, 269
exercises, 270

6: constants, 271
value substitution, 272
const in header files, 273
safety consts, 274
aggregates, 275
differences with C, 276
pointers, 277
pointer to const, 277
const pointer, 278
assignment and type checking, 279
function arguments & return values, 280
passing by const value, 281
returning by const value, 282
passing and returning addresses, 284
classes, 288
const and enum in classes, 288
compile-time constants in classes, 291
const objects & member functions, 294
ROMability, 299
volatile, 300
summary, 302
exercises, 302

7: inline functions, 305
preprocessor pitfalls, 306
macros and access, 310
inline functions, 310
inlines inside classes, 312
access functions, 313
inlines & the compiler, 319
limitations, 320
order of evaluation, 321
hidden activities in constructors & destructors, 322
reducing clutter, 323
preprocessor features, 325
token pasting, 326
improved error checking, 326
summary, 329
exercises, 329

8: name control, 331
static elements from C, 332
static variables inside functions, 332
controlling linkage, 338
other storage class specifiers, 339
namespaces, 340
creating a namespace, 341
using a namespace, 343
static members in C++, 347
defining storage for static data members, 348
nested and local classes, 352
static member functions, 353
static initialization dependency, 356
what to do, 357
alternate linkage specifications, 361
summary, 362
exercises, 362

9: references & the copy-constructor, 365
pointers in C++, 366
references in C++, 366
references in functions, 368
argument-passing guidelines, 371
the copy-constructor, 371
passing & returning by value, 371
copy-construction, 378
default copy-constructor, 385
alternatives to copy-construction, 388
pointers to members, 390
functions, 392
summary, 395
exercises, 396

10: operator overloading, 397
warning & reassurance, 398
syntax, 398
overloadable operators, 400
unary operators, 400
binary operators, 406
arguments & return values, 419
unusual operators, 422
operators you can't overload, 427
nonmember operators, 428
basic guidelines, 430
overloading assignment, 431
behavior of operator=, 433
automatic type conversion, 446
constructor conversion, 446
operator conversion, 448
a perfect example: strings, 451
pitfalls in automatic type conversion, 453
summary, 456
exercises, 456

11: dynamic object creation, 459
object creation, 460
C's approach to the heap, 462
operator new, 464
operator delete, 464
a simple example, 465
memory manager overhead, 466
early examples redesigned, 467
heap-only string class, 467
stash for pointers, 470
the stack, 475
new & delete for arrays, 477
making a pointer more like an array, 479
running out of storage, 479
overloading new & delete, 481
overloading global new & delete, 482
overloading new & delete for a class, 484
overloading new & delete for arrays, 487
constructor calls, 490
object placement, 491
summary, 494
exercises, 494

12: inheritance & composition, 497
composition syntax, 498
inheritance syntax, 500
the constructor initializer list, 502
member object initialization, 503
built-in types in the initializer list, 503
combining composition & inheritance, 505
order of constructor & destructor calls, 507
name hiding, 509
functions that don't automatically inherit, 510
choosing composition vs. inheritance, 513
subtyping, 515
specialization, 518
private inheritance, 520
protected, 521
protected inheritance, 523
multiple inheritance, 523
incremental development, 523
upcasting, 524
why "upcasting"?, 526
composition vs. inheritance (revisited), 527
pointer & reference upcasting, 528
a crisis, 529
summary, 529
exercises, 530

13: polymorphism & virtual functions, 531
evolution of C++ programmers, 532
upcasting, 533
the problem, 535
function call binding, 535
virtual functions, 536
extensibility, 537
how C++ implements late binding, 541
storing type information, 542
picturing virtual functions, 544
under the hood, 546
installing the vpointer, 547
objects are different, 548
why virtual functions?, 549
abstract base classes and pure virtual functions, 551
pure virtual definitions, 556
inheritance and the VTABLE, 557
virtual functions & constructors, 563
order of constructor calls, 564
behavior of virtual functions inside constructors, 565
destructors and virtual destructors, 566
virtuals in destructors, 568
summary, 569
exercises, 570

14: templates & container classes, 573
containers & iterators, 574
the need for containers, 577
overview of templates, 578
the C approach, 578
the Smalltalk approach, 579
the template approach, 581
template syntax, 583
non-inline function definitions, 585
the stack as a template, 586
constants in templates, 589
stash and stack as templates, 591
the ownership problem, 591
stash as a template, 592
stack as a template, 598
string & integer, 603
a string on the stack, 603
integer, 605
vectors, 606
an "infinite" vector, 607
a set, 610
an associative array, 614
templates & inheritance, 618
design & efficiency, 623
preventing template bloat, 623
polymorphism & containers, 625
container types, 629
function templates, 633
a memory allocation system, 633
applying a function to a tstack, 637
member function templates, 640
controlling instantiation, 641
summary, 643
exercises, 644

15: multiple inheritance, 647
perspective, 648
duplicate subobjects, 650
ambiguous upcasting, 651
virtual base classes, 653
the "most derived" class and virtual base initialization, 654
"tying off" virtual bases with a default constructor, 656
overhead, 658
upcasting, 660
persistence, 663
avoiding MI, 672
repairing an interface, 673
summary, 678
exercises, 679

16: exception handling, 681
error handling in C, 682
throwing an exception, 685
catching an exception, 686
the try block, 687
exception handlers, 687
the exception specification, 689
better exception specifications?, 693
catching any exception, 693
rethrowing an exception, 694
uncaught exceptions, 694
cleaning up, 697
constructors, 701
making everything an object, 704
exception matching, 707
standard exceptions, 709
programming with exceptions, 711
when to avoid exceptions, 711
typical uses of exceptions, 713
overhead, 718
summary, 718
exercises, 719

17: run-time type identification, 721
the "shape" example, 722
what is RTTI?, 723
Two syntaxes for RTTI, 724
syntax specifics, 729
typeid( ) with built-in types, 729
producing the proper type name, 729
nonpolymorphic types, 730
casting to intermediate levels, 730
void pointers, 732
using RTTI with templates, 732
references, 733
exceptions, 734
multiple inheritance, 735
sensible uses for RTTI, 736
revisiting the trash recycler, 738
mechanism & overhead of RTTI, 741
creating your own RTTI, 742
new cast syntax, 747
static_cast, 749
const_cast, 751
reinterpret_cast, 752
summary, 755
exercises, 756

A: et cetera, 757
bool, true, and false, 758
new include format, 759
the Standard C++ Libraries, 760
the Standard Template Library (STL), 762
the asm keyword, 766
explicit operators, 767

B: programming guidelines, 769

C: simulating virtual constructors, 781
all-purpose virtual constructors, 782
a remaining conundrum, 787
a simpler alternative, 789

where to find it, 793

