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.
FeaturesYou 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.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)
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)
while(condition) statement
Needs to be:
while(condition) statement
(The above correction has been made in printings after February 1997)
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)
Needs to be: all italics standard font
(The above correction has been made in printings after February 1997)
Needs to be: in the source file containing main().
(The above correction has been made in printings after June 1997)
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)
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)
(The above correction has been made in printings after June 1997)
Needs to be: s with i as a subscript
(The above correction has been made in printings after June 1997)
Needs to be: pips p; //1 < pips <= 13
(The above correction has been made in printings after October 1997)
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)
Needs to be: //delete old string
(The above correction has been made in printings after October 1997)
Needs to be: void push(u_stack* stk, rbdata c)
(The above correction has been made in printings after June 1997)
Needs to be: y = x.d.x;
(The above correction has been made in printings after June 1997)
Needs to be: void assign(complex* pc, double r, double i=0.0)
(The above correction has been made in printings after June 1997)
Needs to be: int k = (rand() % (52 - i));
(The above correction has been made in printings after October 1997)
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)
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)
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)
Needs to be: using X::c, it references the outer class variable;
(The above correction has been made in printings after February 1997)
Needs to be: static_cast < suit > (n
(The above correction has been made in printings after February 1997)
Needs to be: A data member that is declared static ...
(The above correction has been made in printings after October 1997)
Needs to be: const ch_stack::int max_len; //declaration required
(The above correction has been made in printings after October 1997)
Needs to be: void init
(The above correction has been made in printings after February 1997)
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(); }
Needs to be: In the class ch_stack the member ...
(The above correction has been made in printings after October 1997)
Needs to be: .... "y", "z", "{", "|", "}", ....
(The above correction has been made in printings after February 1997)
Needs to be: In file ch_stack4.h
(The above correction has been made in printings after October 1997)
Needs to be: :max_len(str.max_len, top(str.top)
(The above correction has been made in printings after October 1997)
Needs to be: stack (const stack& str); //copy constructor
(The above correction has been made in printings after October 1997)
Needs to be: because it is not intended as an implicit conversion
(The above correction has been made in printings after October 1997)
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)
Needs to be: assert(i >= 0 && i <= ub1() && j >= 0 && j <=ub2());
(The above correction has been made in printings after June 1997)
Needs to be: ... , add a default
(The above correction has been made in printings after October 1997)
Needs to be: int ub() const
(The above correction has been made in printings after June 1997)
Needs to be: strcpy(p, s)
(The above correction has been made in printings after October 1997)
Needs to be: page 189)
(The above correction has been made in printings after June 1997)
Needs to be: unsigned long
(The above correction has been made in printings after June 1997)
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)
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)
Needs to be: element-type& operator[]( integral type);
(The above correction has been made in printings after October 1997)
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)
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)
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)
Needs to be: friend istream& operator >>(istream& in , rational& x);
Needs to be: exercise
(The above correction has been made in printings after June 1997)
Needs to be: that is useful
(The above correction has been made in printings after June 1997)
Needs to be: return *this;
(The above correction has been made in printings after October 1997)
Needs to be: return *this;
(The above correction has been made in printings after October 1997)
Needs to be: return ptr;
(The above correction has been made in printings after October 1997)
Explanation: This program has been added to the website.
(The above correction requires no changes to the text.)
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)
Needs to be: { this -> tick(); return *this; }
(The above correction has been made in printings after October 1997)
Needs to be: use an integer argument
(The above correction has been made in printings after February 1997)
Needs to be: j >= 0
(The above correction has been made in printings after June 1997)
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)
void swap(my_string x, my_string y)Needs to be:
void swap(my_string& x, my_string& y)
Needs to be: //100 char stack
(The above correction has been made in printings after February 1997)
Needs to be: //(500) //500 complex
(The above correction has been made in printings after February 1997)
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)
Needs to be: The benefits of this parameterization include allocation off the stack
(The above correction has been made in printings after October 1997)
Needs to be: The following constructors for
vector
(The above correction has been made in printings after October 1997)
Needs to be: return p[i];
(The above correction has been made in printings after October 1997)
Needs to be: return front;
(The above correction has been made in printings after October 1997)
Needs to be: The generic tree type gen_tree...
(The above correction has been made in printings after October 1997)
Needs to be: while (cin >> dat) {
(The above correction has been made in printings after October 1997)
Needs to be: class
(The above correction has been made in printings after June 1997)
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)
Needs to be: init(even);
(The above correction has been made in printings after October 1997)
Needs to be: operator.
(The above correction has been made in printings after June 1997)
Needs to be: class student_worker
(The above correction has been made in printings after June 1997)
Needs to be: worker {
(The above correction has been made in printings after June 1997)
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)
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)
Needs to be: class student and class worker
(The above correction has been made in printings after June 1997)
Needs to be: s_tree.
(The above correction has been made in printings after June 1997)
Needs to be: worker {
(The above correction has been made in printings after June 1997)
Needs to be: tool kits
(The above correction has been made in printings after June 1997)
Needs to be: catch"
(The above correction has been made in printings after February 1997)
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)
Needs to be: << "bad cast"
(The above correction has been made in printings after June 1997)
Needs to be: price.
(The above correction has been made in printings after June 1997)
Needs to be: Budd (1991)
(The above correction has been made in printings after June 1997)
Needs to be: ! ~ &
Needs to be: bus_stop[i]
Needs to be: typedef int BOOLEAN;
Needs to be: ! ~ &
Needs to be: int a = -5, b = 3, c = 0;
Needs to be: true,
(The above correction has been made in printings after June 1997)
Needs to be: the (with one space only)
(The above correction has been made in printings after June 1997)
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),
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)
Needs to be: problematic.
(The above correction has been made in printings after June 1997)
Needs to be: t,
(The above correction has been made in printings after June 1997)
Needs to be: int good():
Needs to be: operator void*() const;
Needs to be: class
(The above correction has been made in printings after June 1997)
Needs to be: class
(The above correction has been made in printings after June 1997)
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)
4, 5, 24, 27, 38, 128, 152, 183, 210, 299, 343, 353, 410
(The above correction has been made in printings after February 1997)