Object-Oriented Programming Using C++, 2nd Edition

by Ira Pohl


Addison-Wesley ISBN 0-201-89550-1

Object-Oriented Programming Using C++, Second Edition provides the experienced programmer with a clear and thorough introduction to the object-oriented paradigm using ANSI C++. Each chapter introduces you to specific C++ language features that support object-oriented programming concepts, including the most recent additions to the language such as STL, namespaces, RTTI, and the bool type. Best-selling author and C++ authority, Ira Pohl, employs his trademark approach of "dissection" to demonstrate key programming elements and idioms and to teach you how to evaluate tradeoffs and make critical design choices.

Features

You can buy this book online through Barnes and Noble. For the less experienced programmer, C++ by Dissection teaches the C++ language and programming techniques using a sound and structured method.

The C++ code examples in the book are available in several forms. The code is arranged in directories corresponding to the chapters of the book. To get to the unpacked version for any system, or to get individual program files, you can use the FTP directory (www.cse.ucsc.edu/~pohl/OPUS2/). Files are also available in zip form for Windows users and compressed tar form for UNIX users.


Additional C++ Code Examples

Ira has provided additional code to demonstrate dynamic cast, complete clock program, multiple inheritance, mutable members, string constructors, and rvalue vs. lvalue.


Errata

Some of these errata have been corrected in later printings. A note with the approximate month for the correction is at the end of any corrections which may already have been made.

Caveats: Some standard libraries may have been modified since this book was written and the function prototypes may differ from what is available on your compiler. Check your compiler vendor for the correct prototypes.

Notations: p425 means page 425  
                            +8 means 8 lines from top 
                             -7 means 7 lines from bottom

If you encounter errata in this book not listed here, please contact Ira Pohl via email at pohl@cse.ucsc.edu with your errata. You will be cited in the correction if you are the first to report it.

Acknowledgments: I'd like to thank Paul Sevinc of the Swiss Federal Institute of Technology for his careful reading of the text.
p. 6 (Charles Funderburke) in string1.cpp the assign() function is missing from the book, though it does show up in the 'string1.cpp' program in 'opus2d.tar.Z' that can be obtained from the Addison-Wesley web site.

Explanation: Yes, in many instances code was not included in classes. This is not an errata, but an intentional decision to have a declaration, but no definition(code body). Later in the text, there is a completed example see Section 6.4 An Example: Dynamically Allocated Strings. As indicated, the full code as developed under Borland C++ is included at the addison-wesley-longman book site. As a text, some of these omissions leads to exercises testing the students understanding. Also to include and complete all code in the text would be distracting.

(No correction to text is required)


p. 10 (Vincente Lara) line 1: version o*f the

Needs to be: version of the

(The above correction has been made in printings after June 1997)


p11 () The following code causes a memory leak

my_string& operator+ (const my_string& a, const my_string& b)
{
my_string* temp = new my_string(a.len + b.len);
strcpy(temp ->s, a.s);
strcat(temp->s, b.s);
return *temp;
}

In this example, the returned object is copied and abandoned. The following code fixes this:

my_string& operator+ (const my_string& a, const my_string& b)
{
my_string temp =my_string(a.len + b.len);
strcpy(temp.s, a.s);
strcat(temp.s, b.s);
return temp;
}


p. 38 (Dolsberry) kIlometers

Needs to be: to kilometers (not capital I)

(The above correction has been made in printings after February 1997)


p. 46 (Dolsberry) wrong font and indent on while statement
while(condition)
statement

Needs to be:

while(condition)
   statement

(The above correction has been made in printings after February 1997)


p. 47 (Paul Sevinc) for (for-init-statement condition; expression) needs to be for(for-init-statement; condition; expression)

Explanation: The syntax is correct as given. It is changed from the early form of for statement. The new for statement has local scope for any declarations in the for-init-statement. A for-init-statement may itself be either a simple-declaration or an expression statement. Syntactically the semicolon token is implicit.

(No correction to text is required)


p. 49 (Dolsberry) next statement in wrong font

Needs to be: all italics standard font

(The above correction has been made in printings after February 1997)


p68 (Hill) at end of paragraph "...in main()."

Needs to be: in the source file containing main().

(The above correction has been made in printings after June 1997)


p. 81 (Paul Sevinc) last line static_cast<int>(gp); is used. But on p97 midpage: reinterpret_cast<int>(gp); is used. Why the discrepancy?

Needs to be: static_cast<int>(gp);

Explanation: Both work on Borland 5.0 ANSII standard suggests that reinterpret_cast<> is more correct.

(The above correction has been made in printings after June 1997)


p. 83 (Paul Sevinc) line 20: change a single #define ...

Needs to be: change a single const declaration to process ...

Explanation: #define was a carry over from C style use of the preprocessor. Unlike C, C++ allows such const declarations to be used to declare array sizes.

(The above correction has been made in printings after June 1997)


p87 (Hill) comment is confusing Needs to be: *p = 7; //*p is lvalue of a, so a is assigned 7

(The above correction has been made in printings after June 1997)


p. 93 (Vincente Lara) line 5 from bottom: si

Needs to be: s with i as a subscript

(The above correction has been made in printings after June 1997)


p108 (Jason Christensen) line 6: pops should be pips

Needs to be: pips p; //1 < pips <= 13

(The above correction has been made in printings after October 1997)


p110 (Jason Christensen) line in table: suit should be just s

Needs to be:

cd.suit      pc -> s          spades
deck[0].p    deck -> p        5
(*pc).suit   pc -> s          spades

(The above correction has been made in printings after October 1997)


p112 and 113 (Sharon Harvey) line 12: Comment for retrieve old string is incorrect. It should indicate string is to be deleted.

Needs to be: //delete old string

(The above correction has been made in printings after October 1997)


p. 116 (Paul Sevinc) line -6: void push(u_stack* stk, str[i...

Needs to be: void push(u_stack* stk, rbdata c)

(The above correction has been made in printings after June 1997)


p. 117 (Paul Sevinc) line 10: y = x.d.i;

Needs to be: y = x.d.x;

(The above correction has been made in printings after June 1997)


p. 117 (Paul Sevinc) line -5: void assign(complex* pc;...

Needs to be: void assign(complex* pc, double r, double i=0.0)

(The above correction has been made in printings after June 1997)


p121 (Jason Christensen) line 5: extra parentheses are not needed.

Needs to be: int k = (rand() % (52 - i));

(The above correction has been made in printings after October 1997)


p141 (Jason Christensen) line -12: Since ch_stack is a structure, class is incorrect. Use either struct or better yet the generic term class.

Needs to be: This avoids having to clutter the class definition ... (without font change)

(The above correction has been made in printings after October 1997)


p142 (Jason Christensen) line 10: The first sentence in the Access:private and public section should not refer only to functions.

Needs to be: The concept of struct is augmented in C++ to allow public and private members.

(The above correction has been made in printings after October 1997)


p. 147 (Pohl)
class X {    //outer class declaration X::
public: 
...
private:
   char c;       //X::c

Needs to be:

class X {            //outer class declaration  X::
   char  c;          //X::c
public:
   class Y {         //inner class declaration  X::Y::
   public:
      void foo(char e) {X t; ::c = t.X::c = c = e;}
   private:
      char  c;       //X::Y::c
   };
};

(The above correction has been made in printings after February 1997)


p. 147 (Pohl) Next to last paragraph, using X::c, it references the out class variable X::Y::c;

Needs to be: using X::c, it references the outer class variable;

(The above correction has been made in printings after February 1997)


p.149 (Pohl) suit(n

Needs to be: static_cast < suit > (n

(The above correction has been made in printings after February 1997)


p150 (Jason Christensen) line -0: declare should be declared

Needs to be: A data member that is declared static ...

(The above correction has been made in printings after October 1997)


p152 (Jason Christensen) line 7: stack needs to be ch_stack

Needs to be: const ch_stack::int max_len; //declaration required

(The above correction has been made in printings after October 1997)


p. 152 (Park) c_pair init

Needs to be: void init

(The above correction has been made in printings after February 1997)


p. 156 (Paul Ezust)

On P.156, in your example mutable.cpp, the function person::bday() must be declared const in order for the compiler to permit it to be called via the const object ira.

With or without mutable, a const object can only invoke const member functions.

If you change it to:

void bday() const { ++age;}
The program compiles and the mutability point is made.

Needs to be:

The indicated change corrects the problem. The following code is a small variation on the book that incorporates the correction.

#include <  iostream  >
#include <  string  >
using  namespace std;

class person {
public:
  person(const string n, int a, const unsigned long ss)
      :name(n), age(a), soc_sec(ss){}
  void bday() const  {++age;}
  void print() const
  { 
     cout << name << " is  " << age 
     << "  years old with SSN  " << soc_sec << endl;
  }
private:
  const string name;
  mutable int age;
  const unsigned long soc_sec;
};

int main()
{
   const person ira("ira pohl", 38, 1110111UL);
   ira.print();
   ira.bday();
   ira.print();

}

p160 (Jason Christensen) line -12: stack needs to be ch_stack p160 (Jason Christensen) line -12: stack needs to be ch_stack

Needs to be: In the class ch_stack the member ...

(The above correction has been made in printings after October 1997)


p. 170 (Vincente Lara) last line .... "y", "z", ""{", "|", "}", ....

Needs to be: .... "y", "z", "{", "|", "}", ....

(The above correction has been made in printings after February 1997)


p172 (Jason Christensen) line 1: The stack.h file contains the class ch_stack

Needs to be: In file ch_stack4.h

(The above correction has been made in printings after October 1997)


p173 (Sharon Harvey) line -5: Unneeded semicolon at the end of the function header for the stack constructor.

Needs to be: :max_len(str.max_len, top(str.top)

(The above correction has been made in printings after October 1997)


p175 (Sharon Harvey) line -16: missing semicolon on constructor

Needs to be: stack (const stack& str); //copy constructor

(The above correction has been made in printings after October 1997)


p. 181 (Brian Suchomel) line -10 ... because it is not intend as a implicit conversion

Needs to be: because it is not intended as an implicit conversion

(The above correction has been made in printings after October 1997)


p189 (Terrell Koken) line 2-4: Use multidimensional instead of higher-dimensional to talk about arrays of more than one dimension.

Needs to be: Standard C does not have authentic multidimensional arrays. .... can implement flexible, safe, dynamic multidimensional arrays.

(The above correction has been made in printings after October 1997)


p. 190 (Paul Sevinc) line 18: assert(i >= 0 || i <= ub1() || j >= 0 || j <=ub2());

Needs to be: assert(i >= 0 && i <= ub1() && j >= 0 && j <=ub2());

(The above correction has been made in printings after June 1997)


p. 205 (Brian Suchomel) line 8 ... , and include a default

Needs to be: ... , add a default

(The above correction has been made in printings after October 1997)


p206 (author) exercise 11 int ub const

Needs to be: int ub() const

(The above correction has been made in printings after June 1997)


p213 (Sharon Harvey) line 5: The strcpy(s, p) has the argument order reversed.

Needs to be: strcpy(p, s)

(The above correction has been made in printings after October 1997)


p. 218 (Paul Sevinc) line 2: page 189,) (has unneeded comma)

Needs to be: page 189)

(The above correction has been made in printings after June 1997)


p. 224 (Paul Sevinc) line -10: unsigned int

Needs to be: unsigned long

(The above correction has been made in printings after June 1997)


p225 (David Hiebeler) line 15-17: The vect example had ub() as a member function.

Needs to be: Two sentences in the second paragraph on page 226 need to be removed. They are "The public data member ub is changed to a member function. This prevents a user from inadvertently introducing a program error by modifying the member."

(The above correction has been made in printings after October 1997)


p226 (Terrell Koken) line 10: The vect operator= needs to be in the class

Needs to be:

class vect {
   ...
   int& operator[](int i) const ;   //range checked element
   vect& operator=(const vect& v);  //assignment
   ...

(The above correction has been made in printings after October 1997)


p227 (Sharon Harvey) line 9: The class-name should reference instead the type of the array element.

Needs to be: element-type& operator[]( integral type);

(The above correction has been made in printings after October 1997)


p. 228 (Paul Sevinc) line 5: return (*this)

Needs to be: return *this

Explanation: It is the style of this book to not use parentheses with a simple return argument.

(The above correction has been made in printings after June 1997)


p. 228 (Vincente Lara) line 16-17
	  assert(size == v.size):
	  vect sum(s):
	  for (int i = 0; i < s; ++i)
Needs to be:
	  assert(size == v.size):
	  vect sum(size):
	  for (int i = 0; i < size; ++i)

(The above correction has been made in printings after June 1997)


p. 230 (Pohl) midpage
 
friend polynomial&  operator-(const polynomial& a);
friend polynomial&  operator+=(const polynomial& a,
			       const polynomial& b);
Needs to be:
 
friend polynomial  operator-(const polynomial& a);
friend polynomial&  operator+=(polynomial& a,
			       const polynomial& b);
Explanation: The operator += needs to modify its first argument. The operator - is unary and should return its arguments value negated, but should not self-referentially negate the polynomial.

(The above correction has been made in printings after February 1997)


p231 (C. L. Tondo) line 9: Function missing semicolon

Needs to be: friend istream& operator >>(istream& in , rational& x);


p. 232 (Paul Sevinc) line -35: exercise exercise

Needs to be: exercise

(The above correction has been made in printings after June 1997)


p. 232 (Paul Sevinc) line -7: that i useful

Needs to be: that is useful

(The above correction has been made in printings after June 1997)


p234 (Jason Christensen) line 8: It is the style of the book not to parenthesize simple arguments such as *this

Needs to be: return *this;

(The above correction has been made in printings after October 1997)


p235 (Jason Christensen) line 14: It is the style of the book not to parenthesize simple arguments such as *this

Needs to be: return *this;

(The above correction has been made in printings after October 1997)


p236 (Jason Christensen) line -8: It is the style of the book not to parenthesize simple arguments such as ptr

Needs to be: return ptr;

(The above correction has been made in printings after October 1997)


p. 236 (Brian Suchomel) The program triple.cpp is not in the downloadable program set from the website.

Explanation: This program has been added to the website.

(The above correction requires no changes to the text.)


p. 241 (Brian Suchomel) The program over_new.cpp is not complete in the downloadable program set from the website.

Explanation: This program was erroneously a copy of new_hdler.cpp. The over_new.cpp file has been corrected to flesh out the example code as found on page 241.

(The above correction has been made to the website)


p244 (Jason Christensen) line 17: It is the style of the book not to parenthesize simple arguments such as *this

Needs to be: { this -> tick(); return *this; }

(The above correction has been made in printings after October 1997)


p. 251 (Dolsberry) In Exercise 18 - "use a default integer argument"

Needs to be: use an integer argument

(The above correction has been made in printings after February 1997)


p. 256 (Paul Sevinc) line 4: j != 0

Needs to be: j >= 0

(The above correction has been made in printings after June 1997)


p258 (Jason Christensen) line 16: p + size is incorrect; need bp + size instead

Needs to be: This is why the member function vector::end() returns bp + size.

(The above correction has been made in printings after October 1997)


p273 (Alexander Yakhnis) line -7 The swap() code needs to have different arguments:
void swap(my_string x, my_string y)
Needs to be:
void swap(my_string& x, my_string& y)

p. 279 (Pohl) //1000 char stack

Needs to be: //100 char stack

(The above correction has been made in printings after February 1997)


p. 279 (Pohl) (100) //100 complex

Needs to be: //(500) //500 complex

(The above correction has been made in printings after February 1997)


p. 282 (Dolsberry) line -3: Bad spacing on comments initializer list.

Needs to be:

swap(str1[50], str2[33]);  //both char variables -okay
swap(i, ch);               //i int ch char - illegal
swap(str1, str2);          //illegal: attempts to swap arrays

(The above correction has been made in printings after October 1997)


p285 (Jason Christensen) line 15: allocation is from the stack (or off the stack), not of the stack.

Needs to be: The benefits of this parameterization include allocation off the stack

(The above correction has been made in printings after October 1997)


p286 (Jason Christensen) line 23: vect should be vector

Needs to be: The following constructors for vector use T as the ...

(The above correction has been made in printings after October 1997)


p287 (Jason Christensen) line -4: It is the style of the book not to parenthesize simple arguments such as p[i]

Needs to be: return p[i];

(The above correction has been made in printings after October 1997)


p290 (Jason Christensen) line -14: It is the style of the book not to parenthesize simple arguments such as front

Needs to be: return front;

(The above correction has been made in printings after October 1997)


p292 (Jason Christensen) line 13: gentree should be gen_tree

Needs to be: The generic tree type gen_tree...

(The above correction has been made in printings after October 1997)


p294 (Jason Christensen) line 19: Bad spacing around cin and {.

Needs to be: while (cin >> dat) {

(The above correction has been made in printings after October 1997)


p. 309 (Paul Sevinc) line 4 and 7: Class (uppercase incorrect)

Needs to be: class

(The above correction has been made in printings after June 1997)


p319 (Jason Christensen) line 12: Bad spacing on int i= 0 and int j= 0

Needs to be:

   for (int i = 0; i < how_many - 2; ++i)
     for (int j = 0; j < how_many - 1 - i; ++j)

(The above correction has been made in printings after October 1997)


p. 339 (David Hiebeler) line -3: The init(odd); call should be removed. The first call to update(odd, even) creates (inits) odd, when no dele(odd) has yet been called. The code as is will leave a little pile of lost heap memory lying around.Change the line with init(odd); init(even);

Needs to be: init(even);

(The above correction has been made in printings after October 1997)


p. 343 (Dolsberry) line -8 Next to last paragraph operator . has space before period

Needs to be: operator.

(The above correction has been made in printings after June 1997)


p. 343 (Paul Sevinc) line 1: class plans

Needs to be: class student_worker

(The above correction has been made in printings after June 1997)


p. 343 (Paul Sevinc) line 20: worker{

Needs to be: worker {

(The above correction has been made in printings after June 1997)


p. 343 (Paul Sevinc) line -3: public virtual

Needs to be: virtual public

Explanation: While public virtual and virtual public are both allowed interchangeably, the preferred style is virtual public.

(The above correction has been made in printings after June 1997)


p. 344 (Paul Sevinc) line 1: public virtual student

Needs to be: virtual public person

Explanation: While public virtual and virtual public are both allowed interchangeably, the preferred style is virtual public. The inheritance should be from class person, and not class student.

(The above correction has been made in printings after June 1997)


p. 344 (Paul Sevinc) line 3: class::student and class::worker

Needs to be: class student and class worker

(The above correction has been made in printings after June 1997)


p. 353 (Dolsberry) Exercise 7 ends with s_tree .,

Needs to be: s_tree.

(The above correction has been made in printings after June 1997)


p.355 worker{

Needs to be: worker {

(The above correction has been made in printings after June 1997)


p. 356 (Dolsberry) toolkits

Needs to be: tool kits

(The above correction has been made in printings after June 1997)


p. 374 (Pohl) catch\n"

Needs to be: catch"

(The above correction has been made in printings after February 1997)


p. 374 (Pohl) Remove the phrase "and is declared in the file exception" at the end of the first text paragraph.

Remove the word "also" in the phrase "is also declared" in the second text paragraph.

Change (){ to () { (occurs twice on the page)

Change ;} to ; } (occurs twice on the page)

(The above correction has been made in printings after February 1997)


p. 375 (Dolsberry) <<"bad cast"

Needs to be: << "bad cast"

(The above correction has been made in printings after June 1997)


p. 387 (Dolsberry) price .

Needs to be: price.

(The above correction has been made in printings after June 1997)


p. 392 (Paul Sevinc) line 5: Budd (191)

Needs to be: Budd (1991)

(The above correction has been made in printings after June 1997)


p403 (C. L. Tondo) line (in table): There should be more space between the exclamation point and tilde.

Needs to be: ! ~ &


p409 (C. L. Tondo) line -2: The closing ] in bus_stop[i] is in the wrong font.

Needs to be: bus_stop[i]


p411 (C. L. Tondo) line -3: BOOLEAN needs semicolon for consistency with the other typedefs

Needs to be: typedef int BOOLEAN;


p422 (C. L. Tondo) line (in table): There should be more space between the exclamation point and tilde.

Needs to be: ! ~ &


p426 (C. L. Tondo) line (in table): int not needed before b.

Needs to be: int a = -5, b = 3, c = 0;


p. 428 (Dolsberry) true ,

Needs to be: true,

(The above correction has been made in printings after June 1997)


p. 438 (Dolsberry) the (followed by two spaces)

Needs to be: the (with one space only)

(The above correction has been made in printings after June 1997)


p454 (C. L. Tondo) line 5-6: In keeping with general style of using const for arguments which won't be changed, the constructors should use const

Needs to be:

 vect_bnd(const vect_bnd& v);      //copy constructor
 vect_bnd(const vect& v);          //conversion constructor
.....

//conversion constructor
vect_bnd::vect_bnd(const vect& v) :
          vect(v), l_bnd(0), u_bnd(size - 1) { }

//copy constructor
vect_bnd::vect_bnd(const vect_bnd& v) :
          vect(v), 

p. 457 (Jeffrey Peden) line 3-7: Base* and Derived should be switched.

Needs to be:

class Base { .....};
class Derived : Base { ..... };

void fcn(Base* ptr)
{
   Derived* bptr = dynamic_cast<Derived*>(ptr);

In this example, the case converts the pointer value ptr to a Derived*.

(The above correction has been made in printings after June 1997)


p. 468 (Dolsberry) problematic .

Needs to be: problematic.

(The above correction has been made in printings after June 1997)


p. 493 (Dolsberry) t , (should have no space before comma)

Needs to be: t,

(The above correction has been made in printings after June 1997)


p484 (C. L. Tondo) line -10: Semicolon missing after function

Needs to be: int good():


p484 (C. L. Tondo) line -3: Missing semicolon, parenthesis and const from void

Needs to be: operator void*() const;


p. 497 (Paul Sevinc) line 15: Class (uppercase incorrect)

Needs to be: class

(The above correction has been made in printings after June 1997)


p. 497 (Paul Sevinc) line 7, 10, 13: Class (uppercase incorrect)

Needs to be: class

(The above correction has been made in printings after June 1997)


p511 - 515 (Peden) The string library has been modified and the new modifications are not properly reflected in the tables. Multiple changes are needed to bring string into compliance with the new standard. A new example showing the STL string constructors has also been developed.

The changes are listed below:

p511 line 9: seven constructors

Needs to be: six constructors

p511 line 10: Two conversions were removed from the standard. Delete sentence "Two of these ..."

p511 String Constructor Members table entries 3 and 5: Two conversions were removed from the standard. Delete

string(const vector...)
string(size_t size, ...)

p511 String Constructor Members table: One conversion was added to the standard. Insert in place of string(const vector...)

string(InputIterator b, InputIterator e) constructor from the InputInterator range b to e

p511 Last Item in String Constructor Members table has order of arguments reversed. string(char c, size_t n = 1) is incorrect and cannot have the default argument.

Needs to be: string(size_t n, char c)

p512 Third table entry from bottom of String overloaded Operator Members, operator vector< ... should be removed

p512 line -5 order of arguments reversed. append(char c, size_t n = 1) is incorrect and cannot have the default argument.

Needs to be: append(size_t n, char c)

p513 line 6 has order of arguments reversed. assign(char c, size_t n = 1) is incorrect and cannot have the default argument.

Needs to be: assign(size_t n, char c)

p513 line -5 above table has order of arguments reversed. insert(char c, size_t n = 1) is incorrect and cannot have the default argument.

Needs to be: insert(size_t n, char c)

p513 line 6 - needs another assign at end of assigns list

Needs to be: string& assign(InputIterator b, InputIterator e);

p513 line -4 above table needs 3 more inserts at end of inserts list

Needs to be:

iterator insert(iterator p, char c);
iterator insert(iterator p, size_t n, char c);
void insert(iterator p, InputIterator b, InputIterator e);

p513 Second table entry in String Members table has string& replace(pos, n, c, rep = 1); The rep argument has been removed.

Needs to be: string& rplace(pos, n, c); and the comment "repeated rep times" needs to be removed.

p514 Third table entry from bottom in String Members table has comment returns the private member res; the first function resets this which needs to be modified.

Needs to be: allocates memory for string; returns the size of the allocation

p513-514 Third and fourth table entries in String Members table and their explanations should be removed. The two items for removal are: char get_at(pos) const; and void put_at(pos, c);

p514 line -6 has int compare (const char* p, size_t pos) const which needs a default value on last argument.

Needs to be: int compare (const char* p, size_t pos = 0) const

p514 line -5 has int compare (char c, size_t pos, size_t rep = 1) const; which must be removed altogether.

(The above correction has been made in printings after June 1997)


The following pages all need to change curved quotes to straight in program code

4, 5, 24, 27, 38, 128, 152, 183, 210, 299, 343, 353, 410

(The above correction has been made in printings after February 1997)