You are on page 1of 47

11

The whole difference


between construction and
creation is exactly this: that
a thing constructed can only
be loved after it is
constructed; but a thing
created is loved before it
exists.
Gilbert Keith Chesterton

The die is cast.


Julius Caesar

Our doctor would never


really operate unless it was
necessary. He was just that
way. If he didnt need the
money, he wouldnt lay a
hand on you.
Herb Shriner

Operator
Overloading;
String and
Array Objects
OBJECTIVES
In this chapter you will learn:

To redene (overload) operators to work with new


abstract data types (ADTs).

To convert objects from one class to another class.

When to, and when not to, overload operators.

To create Array, String and Date classes that


demonstrate operator overloading.
To use overloaded operators and other member
functions of standard library class string.
To use keyword explicit to prevent the compiler from
using single-argument constructors to perform implicit
conversions.

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Chapter 11 Operator Overloading; String and Array Objects

Self-Review Exercises
11.1

Fill in the blanks in each of the following:


a) Suppose a and b are integer variables and we form the sum a + b. Now suppose c and
d are floating-point variables and we form the sum c + d. The two + operators here are
clearly being used for different purposes. This is an example of
.
ANS: operator overloading.
b) Keyword
introduces an overloaded-operator function definition.
ANS: operator.
c) To use operators on class objects, they must be overloaded, with the exception of oper,
and
.
ators
ANS: assignment (=), address (&), comma (,).
d) The
,
and
of an operator cannot be changed by
overloading the operator.
ANS: precedence, associativity, arity.

11.2

Explain the multiple meanings of the operators << and >> in C++.
ANS: Operator >> is both the right-shift operator and the stream extraction operator,
depending on its context. Operator << is both the left-shift operator and the stream
insertion operator, depending on its context.

11.3

In what context might the name operator/ be used in C++?


ANS: For operator overloading: It would be the name of a function that would provide an
overloaded version of the / operator for a specific class.

11.4

(True/False) In C++, only existing operators can be overloaded.


ANS: True.

11.5 How does the precedence of an overloaded operator in C++ compare with the precedence
of the original operator?
ANS: The precedence is identical.

Solutions
11.6 Give as many examples as you can of operator overloading implicit in C++. Give a reasonable example of a situation in which you might want to overload an operator explicitly in C++.
ANS: In C, the operators +, -, *, and & are overloaded. The context of these operators determines how they are used. It can be argued that the arithmetic operators are all overloaded, because they can be used to perform operations on more than one type of
data. In C++, the same operators as in C are overloaded, as well as << and >>. One
situation in which you might want to overload an operator would be in the sorting
of objects. In Chapter 7 you were introduced to sorting, where the equality and relational operators were used to determine when a value was greater than, equal to or
less than another value. These operators can be overloaded to compare (and sort) objectsfor instance, sorting GradeBook objects alphabetically by course name.
11.7

The operators that cannot be overloaded are


.
ANS: ., ?:, .*, and ::.

and

11.8 String concatenation requires two operandsthe two strings that are to be concatenated.
In the text, we showed how to implement an overloaded concatenation operator that concatenates
the second String object to the right of the first String object, thus modifying the first String object. In some applications, it is desirable to produce a concatenated String object without modifying
the String arguments. Implement operator+ to allow operations such as
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
string1 = string2 + string3;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

// Exercise 11.8 Solution: String.h


// Header file for class String.
#ifndef STRING_H
#define STRING_H

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

// Exercise 11.8 Solution: String.cpp


// Member-function definitions for String.cpp
#include <iostream>
using std::cout;
using std::ostream;

#include <cstring>
#include <cassert>
class String
{
friend ostream &operator<<( ostream &output, const String &s );
public:
String( const char * const = "" ); // conversion constructor
String( const String & ); // copy constructor
~String(); // destructor
const String &operator=( const String & );
String operator+( const String & );
private:
char *sPtr; // pointer to start of string
int length; // string length
}; // end class String
#endif

#include <cstring> // strcpy and strcat prototypes


#include "String.h" // String class definition
// conversion constructor: convert a char * to String
String::String( const char * const zPtr )
{
length = strlen( zPtr ); // compute length
sPtr = new char[ length + 1 ]; // allocate storage
assert( sPtr != 0 ); // terminate if memory not allocated
strcpy( sPtr, zPtr ); // copy literal to object
} // end String conversion constructor
// copy constructor
String::String( const String &copy )
{
length = copy.length; // copy length
sPtr = new char[ length + 1 ]; // allocate storage
assert( sPtr != 0 ); // ensure memory allocated
strcpy( sPtr, copy.sPtr ); // copy string

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

4
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
1
2
3
4
5
6
7
8

Chapter 11 Operator Overloading; String and Array Objects

} // end String copy constructor


// destructor
String::~String()
{
delete [] sPtr; // reclaim string
} // end destructor
// overloaded = operator; avoids self assignment
const String &String::operator=( const String &right )
{
if ( &right != this ) // avoid self assignment
{
delete [] sPtr; // prevents memory leak
length = right.length; // new String length
sPtr = new char[ length + 1 ]; // allocate memory
assert( sPtr != 0 ); // ensure memory allocated
strcpy( sPtr, right.sPtr ); // copy string
}
else
cout << "Attempted assignment of a String to itself\n";
return *this; // enables concatenated assignments
} // end function operator=
// concatenate right operand and this object and store in temp object
String String::operator+( const String &right )
{
String temp;
temp.length = length + right.length;
temp.sPtr = new char[ temp.length + 1 ]; // create space
assert( sPtr != 0 ); // terminate if memory not allocated
strcpy( temp.sPtr, sPtr ); // left part of new String
strcat( temp.sPtr, right.sPtr ); // right part of new String
return temp; // enables concatenated calls
} // end function operator+
// overloaded output operator
ostream & operator<<( ostream &output, const String &s )
{
output << s.sPtr;
return output; // enables concatenation
} // end function operator<<

// Exercise 11.8 Solution: ex11_08.cpp


// Demonstrating overloaded + operator that does not modify operands
#include <iostream>
using std::cout;
using std::endl;
#include "String.h"

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
9
10
11
12
13
14
15
16
17
18
19
20

int main()
{
String string1, string2( "The date is" );
String string3( " August 1, 1993" );
// test overloaded operators
cout << "string1 = string2 + string3\n";
string1 = string2 + string3; // tests overloaded = and + operator
cout << "\"" << string1 << "\" = \"" << string2 << "\" + \""
<< string3 << "\"" << endl;
return 0;
} // end main

string1 = string2 + string3


"The date is August 1, 1993" = "The date is" + " August 1, 1993"

11.9 (Ultimate operator overloading exercise) To appreciate the care that should go into selecting
operators for overloading, list each of C++s overloadable operators, and for each, list a possible
meaning (or several, if appropriate) for each of several classes you have studied in this text. We suggest you try:
a) Array
b) Stack
c) String
After doing this, comment on which operators seem to have meaning for a wide variety of classes.
Which operators seem to be of little value for overloading? Which operators seem ambiguous?
11.10 Now work the process described in Exercise 11.9 in reverse. List each of C++s overloadable
operators. For each, list what you feel is perhaps the ultimate operation the operator should be
used to represent. If there are several excellent operations, list them all.
11.11 One nice example of overloading the function call operator () is to allow another form of
double-array subscripting popular in some programming languages. Instead of saying
chessBoard[ row ][ column ]

for an array of objects, overload the function call operator to allow the alternate form
chessBoard( row, column )

Create a class DoubleSubscriptedArray that has similar features to class Array in Figs. 11.6
11.7. At construction time, the class should be able to create an array of any number of rows and any
number of columns. The class should supply operator() to perform double-subscripting operations.
For example, in a 3-by-5 DoubleSubscriptedArray called a, the user could write a( 1, 3 ) to access
the element at row 1 and column 3. Remember that operator() can receive any number of arguments (see class String in Figs. 11.911.10 for an example of operator()). The underlying representation of the double-subscripted array should be a single-subscripted array of integers with rows *
columns number of elements. Function operator() should perform the proper pointer arithmetic to
access each element of the array. There should be two versions of operator()one that returns int &
(so that an element of a DoubleSubscriptedArray can be used as an lvalue) and one that returns
const int & (so that an element of a const DoubleSubscriptedArray can be used only as an rvalue).

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Chapter 11 Operator Overloading; String and Array Objects

The class should also provide the following operators: ==, !=, =, << (for outputting the array in row
and column format) and >> (for inputting the entire array contents).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

// Exercise 11.11 Solution: DoubleSubscriptedArray.h


// DoubleSubscriptedArray class for storing
// double subscripted arrays of integers.
#ifndef DOUBLE_SUBSCRIPTED_ARRAY_H
#define DOUBLE_SUBSCRIPTED_ARRAY_H
#include <iostream>
using std::ostream;
using std::istream;
class DoubleSubscriptedArray
{
friend ostream &operator<<(
ostream &, const DoubleSubscriptedArray & );
friend istream &operator>>( istream &, DoubleSubscriptedArray & );
public:
DoubleSubscriptedArray( int = 3, int = 3 ); // default constructor
// copy constructor
DoubleSubscriptedArray( const DoubleSubscriptedArray & );
~DoubleSubscriptedArray(); // destructor
int getRowSize() const; // return number of rows
int getColumnSize() const; // return number of columns
const DoubleSubscriptedArray &operator=(
const DoubleSubscriptedArray & ); // assignment operator
// equality operator
bool operator==( const DoubleSubscriptedArray & ) const;
// inequality operator; returns opposite of == operator
bool operator!=( const DoubleSubscriptedArray &right ) const
{
// invokes DoubleSubscriptedArray::operator==
return !( *this == right );
} // end function operator!=
// function call operator for non-const objects
// returns modifiable lvalue
int &operator()( int, int );
// function call operator for const objects returns rvalue
int operator()( int, int ) const;
private:
int rowSize; // number of rows in array
int columnSize; // number of columns in array
int *ptr; // pointer to first element of pointer-based array
}; // end class DoubleSubscriptedArray
#endif

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

// Exercise 11.11 Solution: DoubleSubscriptedArray.cpp


// Member-function definitions for class DoubleSubscriptedArray.
#include <iostream>
using std::cerr;
using std::cout;
using std::cin;
using std::endl;
#include <iomanip>
using std::setw;
#include <cstdlib> // exit function prototype
using std::exit;
// DoubleSubscriptedArray class definition
#include "DoubleSubscriptedArray.h"
// default constructor for class DoubleSubscriptedArray
DoubleSubscriptedArray::DoubleSubscriptedArray(
int rowSizeEntered, int columnSizeEntered )
{
// validate row and column size
rowSize = ( rowSizeEntered > 0 ? rowSizeEntered : 3 );
columnSize = ( columnSizeEntered > 0 ? columnSizeEntered : 3 );
ptr = new int[ rowSize * columnSize ]; // create space for array
for ( int loop = 0; loop < rowSize * columnSize; loop++ )
ptr[ loop ] = 0; // set pointer-based array element
} // end DoubleSubscriptedArray default constructor
// copy constructor for class DoubleSubscriptedArray;
// must receive a reference to prevent infinite recursion
DoubleSubscriptedArray::DoubleSubscriptedArray(
const DoubleSubscriptedArray &arrayToCopy )
: rowSize( arrayToCopy.rowSize ), columnSize( arrayToCopy.columnSize )
{
ptr = new int[ rowSize * columnSize ]; // create space for array
for ( int loop = 0; loop < rowSize * columnSize; loop++ )
ptr[ loop ] = arrayToCopy.ptr[ loop ]; // copy into object
} // end DoubleSubscriptedArray copy constructor
// destructor for class DoubleSubscriptedArray
DoubleSubscriptedArray::~DoubleSubscriptedArray()
{
delete [] ptr; // release pointer-based array space
} // end destructor
// return number of rows of DoubleSubscriptedArray
int DoubleSubscriptedArray::getRowSize() const
{

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

8
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

Chapter 11 Operator Overloading; String and Array Objects

return rowSize; // number of rows in DoubleSubscriptedArray


} // end function getRowSize
// return number of columns of DoubleSubscriptedArray
int DoubleSubscriptedArray::getColumnSize() const
{
return columnSize; // number of columns in DoubleSubscriptedArray
} // end function getColumnSize
// overloaded assignment operator;
// const return avoids: ( a1 = a2 ) = a3
const DoubleSubscriptedArray &DoubleSubscriptedArray::operator=(
const DoubleSubscriptedArray &right )
{
if ( &right != this ) // avoid self-assignment
{
// for arrays of different sizes, deallocate original
// left-side array, then allocate new left-side array
if ( rowSize * columnSize != right.rowSize * right.columnSize )
{
delete [] ptr; // release space
rowSize = right.rowSize; // resize this object
columnSize = right.columnSize;
ptr = new int[ rowSize * columnSize ]; // create space for copy
} // end inner if
for ( int loop = 0; loop < rowSize * columnSize; loop++ )
ptr[ loop ] = right.ptr[ loop ]; // copy into object
} // end outer if
return *this; // enables x = y = z, for example
} // end function operator=
// determine if two DoubleSubscriptedArrays are equal and
// return true, otherwise return false
bool DoubleSubscriptedArray::operator==(
const DoubleSubscriptedArray &right ) const
{
if ( rowSize * columnSize != right.rowSize * right.columnSize )
return false; // arrays of different number of elements
for ( int loop = 0; loop < rowSize * columnSize; loop++ )
if ( ptr[ loop ] != right.ptr[ loop ] )
return false; // DoubleSubscriptedArray contents are not equal
return true; // DoubleSubscriptedArrays are equal
} // end function operator==
// overloaded subscript operator for non-const DoubleSubscriptedArrays;
// reference return creates a modifiable lvalue
int &DoubleSubscriptedArray::operator()(
int rowSubscript, int columnSubscript )
{
// check for subscript out-of-range error

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

if ( ( rowSubscript < 0 || rowSubscript >= rowSize ) ||


( columnSubscript < 0 || columnSubscript >= columnSize ) )
{
cerr << "\nError: One or both subscripts out of range" << endl;
exit( 1 ); // terminate program; one or both subscripts out of range
} // end if
// reference return
return ptr[ ( rowSubscript * columnSize ) + columnSubscript ];
} // end function operator()
// overloaded subscript operator for const DoubleSubscriptedArrays
// const reference return creates an rvalue
int DoubleSubscriptedArray::operator()(
int rowSubscript, int columnSubscript ) const
{
// check for subscript out-of-range error
if ( ( rowSubscript < 0 || rowSubscript >= rowSize ) ||
( columnSubscript < 0 || columnSubscript >= columnSize ) )
{
cerr << "\nError: One or both subscripts out of range" << endl;
exit( 1 ); // terminate program; one or both subscripts out of range
} // end if
// returns copy of this element
return ptr[ ( rowSubscript * columnSize ) + columnSubscript ];
} // end function operator()
// overloaded input operator for class DoubleSubscriptedArray;
// inputs values for entire DoubleSubscriptedArray
istream &operator>>( istream &input, DoubleSubscriptedArray &a )
{
for ( int loop = 0; loop < a.rowSize * a.columnSize; loop++ )
input >> a.ptr[ loop ];
return input; // enables cin >> x >> y;
} // end function operator>>
// overloaded output operator for class DoubleSubscriptedArray
ostream &operator<<( ostream &output, const DoubleSubscriptedArray &a )
{
for ( int loop = 0; loop < a.rowSize; loop++ )
{
for ( int loop2 = 0; loop2 < a.columnSize; loop2++ )
output << a.ptr[ ( loop * a.columnSize ) + loop2 ] << ' ';
output << endl;
} // end for
return output; // enables cout << x << y;
} // end function operator<<

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

Chapter 11 Operator Overloading; String and Array Objects

// Exercise 11.11 Solution: ex11_11.cpp


// DoubleSubscriptedArray class test program.
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
#include "DoubleSubscriptedArray.h"
int main()
{
DoubleSubscriptedArray integers1( 2, 4 ); // seven-element array
DoubleSubscriptedArray integers2; // 3-by-3 array by default
// print integers1 size and contents
cout << "Size of DoubleSubscriptedArray integers1 is "
<< integers1.getRowSize() << " X " << integers1.getColumnSize()
<< "\nDoubleSubscriptedArray after initialization:\n" << integers1;
// print integers2 size and contents
cout << "\nSize of DoubleSubscriptedArray integers2 is "
<< integers2.getRowSize() << " X " << integers2.getColumnSize()
<< "\nDoubleSubscriptedArray after initialization:\n" << integers2;
// input and print integers1 and integers2
cout << "\nEnter 17 integers:" << endl;
cin >> integers1 >> integers2;
cout << "\nAfter input, the DoubleSubscriptedArrays contain:\n"
<< "integers1:\n" << integers1
<< "\nintegers2:\n" << integers2 << endl;
// use overloaded inequality (!=) operator
cout << "Evaluating: integers1 != integers2" << endl;
if ( integers1 != integers2 )
cout << "integers1 and integers2 are not equal" << endl;
// create DoubleSubscriptedArray integers3 using integers1 as an
// initializer with copy constructor; print size and contents
DoubleSubscriptedArray integers3( integers1 );
cout << "\nSize of DoubleSubscriptedArray integers3 is "
<< integers3.getRowSize() << " X " << integers3.getColumnSize()
<< "\nDoubleSubscriptedArray after initialization:\n" << integers3;
// use overloaded assignment (=) operator
cout << "\nAssigning integers2 to integers1:" << endl;
integers1 = integers2; // note target Array is smaller
cout << "integers1:\n" << integers1
<< "\nintegers2:\n" << integers2;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

// use overloaded equality (==) operator


cout << "\nEvaluating: integers1 == integers2" << endl;
if ( integers1 == integers2 )
cout << "integers1 and integers2 are equal" << endl;
// use overloaded subscript operator to create rvalue
cout << "\nintegers1( 1, 2 ) is " << integers1( 1, 2 );
// use overloaded subscript operator to create lvalue
cout << "\n\nAssigning 1000 to integers1( 1, 2 )" << endl;
integers1( 1, 2 ) = 1000;
cout << "integers1:\n" << integers1;
// attempt to use out-of-range subscript
cout << "\nAttempt to assign 1000 to integers1( 15, 2 )" << endl;
integers1( 15, 2 ) = 1000; // ERROR: out of range
return 0;
} // end main

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

11

12

Chapter 11 Operator Overloading; String and Array Objects

Size of DoubleSubscriptedArray integers1 is 2 X 4


DoubleSubscriptedArray after initialization:
0 0 0 0
0 0 0 0
Size of DoubleSubscriptedArray integers2 is 3 X 3
DoubleSubscriptedArray after initialization:
0 0 0
0 0 0
0 0 0
Enter 17 integers:
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
After input, the DoubleSubscriptedArrays contain:
integers1:
10 11 12 13
14 15 16 17
integers2:
18 19 20
21 22 23
24 25 26
Evaluating: integers1 != integers2
integers1 and integers2 are not equal
Size of DoubleSubscriptedArray integers3 is 2 X 4
DoubleSubscriptedArray after initialization:
10 11 12 13
14 15 16 17
Assigning integers2 to integers1:
integers1:
18 19 20
21 22 23
24 25 26
integers2:
18 19 20
21 22 23
24 25 26
Evaluating: integers1 == integers2
integers1 and integers2 are equal
integers1( 1, 2 ) is 23
Assigning 1000 to integers1( 1, 2 )
integers1:
18 19 20
21 22 1000
24 25 26
Attempt to assign 1000 to integers1( 15, 2 )
Error: One or both subscripts out of range

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions

13

11.12 Overload the subscript operator to return the largest element of a collection, the second
largest, the third largest, and so on.
11.13 Consider class Complex shown in Figs. 11.1911.21. The class enables operations on socalled complex numbers. These are numbers of the form realPart + imaginaryPart * i, where i has
the value
1
a) Modify the class to enable input and output of complex numbers through the overloaded >> and << operators, respectively (you should remove the print function from
the class).
b) Overload the multiplication operator to enable multiplication of two complex numbers
as in algebra.
c) Overload the == and != operators to allow comparisons of complex numbers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

// Fig. 11.19: Complex.h


// Complex class definition.
#ifndef COMPLEX_H
#define COMPLEX_H
class Complex
{
public:
Complex( double = 0.0, double = 0.0 ); // constructor
Complex operator+( const Complex & ) const; // addition
Complex operator-( const Complex & ) const; // subtraction
void print() const; // output
private:
double real; // real part
double imaginary; // imaginary part
}; // end class Complex
#endif

Fig. 11.19 |

1
2
3
4
5
6
7
8
9
10
11

Complex

class definition.

// Fig. 11.20: Complex.cpp


// Complex class member-function definitions.
#include <iostream>
using std::cout;
#include "Complex.h" // Complex class definition
// Constructor
Complex::Complex( double realPart, double imaginaryPart )
: real( realPart ),
imaginary( imaginaryPart )

Fig. 11.20 |

Complex

class member-function definitions. (Part 1 of 2.)

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

14
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

Chapter 11 Operator Overloading; String and Array Objects

// empty body
} // end Complex constructor
// addition operator
Complex Complex::operator+( const Complex &operand2 ) const
{
return Complex( real + operand2.real,
imaginary + operand2.imaginary );
} // end function operator+
// subtraction operator
Complex Complex::operator-( const Complex &operand2 ) const
{
return Complex( real - operand2.real,
imaginary - operand2.imaginary );
} // end function operator// display a Complex object in the form: (a, b)
void Complex::print() const
{
cout << '(' << real << ", " << imaginary << ')';
} // end function print

Fig. 11.20 |

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

Complex

class member-function definitions. (Part 2 of 2.)

// Fig. 11.21: fig11_21.cpp


// Complex class test program.
#include <iostream>
using std::cout;
using std::endl;
#include "Complex.h"
int main()
{
Complex x;
Complex y( 4.3, 8.2 );
Complex z( 3.3, 1.1 );
cout << "x: ";
x.print();
cout << "\ny: ";
y.print();
cout << "\nz: ";
z.print();
x = y + z;

Fig. 11.21 | Complex numbers. (Part 1 of 2.)


2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

15

cout << "\n\nx = y + z:" << endl;


x.print();
cout << " = ";
y.print();
cout << " + ";
z.print();
x = y - z;
cout << "\n\nx = y - z:" << endl;
x.print();
cout << " = ";
y.print();
cout << " - ";
z.print();
cout << endl;
return 0;
} // end main

x: (0, 0)
y: (4.3, 8.2)
z: (3.3, 1.1)
x = y + z:
(7.6, 9.3) = (4.3, 8.2) + (3.3, 1.1)
x = y - z:
(1, 7.1) = (4.3, 8.2) - (3.3, 1.1)

Fig. 11.21 | Complex numbers. (Part 2 of 2.)

ANS: [Note: In the solution below, the == operator returns true by comparing double val-

uesa practice that is error-prone due to the way computers handle floating-point
values. You may want to modify the == operator to take the difference between two
doubles and determining if the difference is less than a threshold value such as
0.00001.]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// Exercise 11.13 Solution: Complex.h


// Complex class definition.
#ifndef COMPLEX_H
#define COMPLEX_H
#include <iostream>
using std::ostream;
using std::istream;
class Complex
{
friend ostream &operator<<( ostream &, const Complex & );
friend istream &operator>>( istream &, Complex & );
public:
Complex( double = 0.0, double = 0.0 ); // constructor

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

16

Chapter 11 Operator Overloading; String and Array Objects

16
17
18
19
20
21
22
23
24
25
26
27

Complex operator+( const Complex& ) const; // addition


Complex operator-( const Complex& ) const; // subtraction
Complex operator*( const Complex& ) const; // multiplication
Complex& operator=( const Complex& ); // assignment
bool operator==( const Complex& ) const;
bool operator!=( const Complex& ) const;
private:
double real; // real part
double imaginary; // imaginary part
}; // end class Complex

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

// Exercise 11.13 Solution: Complex.cpp


// Complex class member-function definitions.
#include "Complex.h"

#endif

#include <iostream>
using std::ostream;
using std::istream;
// Constructor
Complex::Complex( double realPart, double imaginaryPart )
: real( realPart ),
imaginary( imaginaryPart )
{
// empty body
} // end Complex constructor
// addition operator
Complex Complex::operator+( const Complex &operand2 ) const
{
return Complex( real + operand2.real,
imaginary + operand2.imaginary );
} // end function operator+
// subtraction operator
Complex Complex::operator-( const Complex &operand2 ) const
{
return Complex( real - operand2.real,
imaginary - operand2.imaginary );
} // end function operator// Overloaded multiplication operator
Complex Complex::operator*( const Complex &operand2 ) const
{
return Complex(
( real * operand2.real ) + ( imaginary * operand2.imaginary ),
( real * operand2.imaginary ) + ( imaginary * operand2.real ) );
} // end function operator*
// Overloaded = operator
Complex& Complex::operator=( const Complex &right )

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

// Exercise 11.13 Solution: ex11_13.cpp


// Complex class test program.
#include <iostream>
using std::cout;
using std::cin;

real = right.real;
imaginary = right.imaginary;
return *this;
// enables concatenation
} // end function operator=
bool Complex::operator==( const Complex &right ) const
{
return ( right.real == real ) && ( right.imaginary == imaginary )
? true : false;
} // end function operator==
bool Complex::operator!=( const Complex &right ) const
{
return !( *this == right );
} // end function operator!=
ostream& operator<<( ostream &output, const Complex &complex )
{
output << "(" << complex.real << ", " << complex.imaginary << ")";
return output;
} // end function operator<<
istream& operator>>( istream &input, Complex &complex )
{
input.ignore(); // skip (
input >> complex.real;
input.ignore( 2 ); // skip ',' and space
input >> complex.imaginary;
input.ignore(); // skip )
return input;
} // end function operator>>

#include "Complex.h"
int main()
{
Complex x, y( 4.3, 8.2 ), z( 3.3, 1.1 ), k;
cout << "Enter a complex number in the form: (a,
cin >> k; // demonstrating overloaded >>
cout << "x: " << x << "\ny: " << y << "\nz: " <<
<< k << '\n'; // demonstrating overloaded <<
x = y + z; // demonstrating overloaded + and =
cout << "\nx = y + z:\n" << x << " = " << y << "
x = y - z; // demonstrating overloaded - and =
cout << "\nx = y - z:\n" << x << " = " << y << "

b)\n? ";
z << "\nk: "
+ " << z << '\n';
- " << z << '\n';

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

17

18
21
22
23
24
25
26
27
28
29
30
31
32
33
34

Chapter 11 Operator Overloading; String and Array Objects

x = y * z; // demonstrating overloaded * and =


cout << "\nx = y * z:\n" << x << " = " << y << " * " << z << "\n\n";
if ( x != k ) // demonstrating overloaded !=
cout << x << " != " << k << '\n';
cout << '\n';
x = k;
if ( x == k ) // demonstrating overloaded ==
cout << x << " == " << k << '\n';
return 0;
} // end main

Enter a complex number in the form: (a, b)


? (0, 0)
x: (0, 0)
y: (4.3, 8.2)
z: (3.3, 1.1)
k: (0, 0)
x = y + z:
(7.6, 9.3) = (4.3, 8.2) + (3.3, 1.1)
x = y - z:
(1, 7.1) = (4.3, 8.2) - (3.3, 1.1)
x = y * z:
(23.21, 31.79) = (4.3, 8.2) * (3.3, 1.1)
(23.21, 31.79) != (0, 0)
(0, 0) == (0, 0)

11.14 A machine with 32-bit integers can represent integers in the range of approximately 2 billion to +2 billion. This fixed-size restriction is rarely troublesome, but there are applications in
which we would like to be able to use a much wider range of integers. This is what C++ was built
to do, namely, create powerful new data types. Consider class HugeInt of Figs. 11.2211.24. Study
the class carefully, then answer the following:
a) Describe precisely how it operates.
b) What restrictions does the class have?
c) Overload the * multiplication operator.
d) Overload the / division operator.
e) Overload all the relational and equality operators.
[Note: We do not show an assignment operator or copy constructor for class HugeInteger, because
the assignment operator and copy constructor provided by the compiler are capable of copying the
entire array data member properly.]

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

// Fig. 11.22: Hugeint.h


// HugeInt class definition.
#ifndef HUGEINT_H
#define HUGEINT_H
#include <iostream>
using std::ostream;
class HugeInt
{
friend ostream &operator<<( ostream &, const HugeInt & );
public:
HugeInt( long = 0 ); // conversion/default constructor
HugeInt( const char * ); // conversion constructor
// addition operator; HugeInt + HugeInt
HugeInt operator+( const HugeInt & ) const;
// addition operator; HugeInt + int
HugeInt operator+( int ) const;
// addition operator;
// HugeInt + string that represents large integer value
HugeInt operator+( const char * ) const;
private:
short integer[ 30 ];
}; // end class HugetInt
#endif

Fig. 11.22 |

1
2
3
4
5
6
7
8
9
10
11
12
13
14

HugeInt

class definition.

// Fig. 11.23: Hugeint.cpp


// HugeInt member-function and friend-function definitions.
#include <cctype> // isdigit function prototype
#include <cstring> // strlen function prototype
#include "Hugeint.h" // HugeInt class definition
// default constructor; conversion constructor that converts
// a long integer into a HugeInt object
HugeInt::HugeInt( long value )
{
// initialize array to zero
for ( int i = 0; i <= 29; i++ )
integer[ i ] = 0;

Fig. 11.23 |

HugeInt

class member-function and friend-function definitions. (Part 1 of 3.)

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

19

20
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

Chapter 11 Operator Overloading; String and Array Objects

// place digits of argument into array


for ( int j = 29; value != 0 && j >= 0; j-- )
{
integer[ j ] = value % 10;
value /= 10;
} // end for
} // end HugeInt default/conversion constructor
// conversion constructor that converts a character string
// representing a large integer into a HugeInt object
HugeInt::HugeInt( const char *string )
{
// initialize array to zero
for ( int i = 0; i <= 29; i++ )
integer[ i ] = 0;
// place digits of argument into array
int length = strlen( string );
for ( int j = 30 - length, k = 0; j <= 29; j++, k++ )
if ( isdigit( string[ k ] ) )
integer[ j ] = string[ k ] - '0';
} // end HugeInt conversion constructor
// addition operator; HugeInt + HugeInt
HugeInt HugeInt::operator+( const HugeInt &op2 ) const
{
HugeInt temp; // temporary result
int carry = 0;
for ( int i = 29; i >= 0; i-- )
{
temp.integer[ i ] =
integer[ i ] + op2.integer[ i ] + carry;
// determine whether to carry a 1
if ( temp.integer[ i ] > 9 )
{
temp.integer[ i ] %= 10; // reduce to 0-9
carry = 1;
} // end if
else // no carry
carry = 0;
} // end for
return temp; // return copy of temporary object
} // end function operator+
// addition operator; HugeInt + int
HugeInt HugeInt::operator+( int op2 ) const
{

Fig. 11.23 |

HugeInt

class member-function and friend-function definitions. (Part 2 of 3.)

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

// convert op2 to a HugeInt, then invoke


// operator+ for two HugeInt objects
return *this + HugeInt( op2 );
} // end function operator+
// addition operator;
// HugeInt + string that represents large integer value
HugeInt HugeInt::operator+( const char *op2 ) const
{
// convert op2 to a HugeInt, then invoke
// operator+ for two HugeInt objects
return *this + HugeInt( op2 );
} // end operator+
// overloaded output operator
ostream& operator<<( ostream &output, const HugeInt &num )
{
int i;
for ( i = 0; ( num.integer[ i ] == 0 ) && ( i <= 29 ); i++ )
; // skip leading zeros
if ( i == 30 )
output << 0;
else
for ( ; i <= 29; i++ )
output << num.integer[ i ];
return output;
} // end function operator<<

Fig. 11.23 |

1
2
3
4
5
6
7
8
9
10
11
12
13
14

HugeInt

class member-function and friend-function definitions. (Part 3 of 3.)

// Fig. 11.24: fig11_24.cpp


// HugeInt test program.
#include <iostream>
using std::cout;
using std::endl;
#include "Hugeint.h"
int main()
{
HugeInt
HugeInt
HugeInt
HugeInt

n1(
n2(
n3(
n4(

7654321 );
7891234 );
"99999999999999999999999999999" );
"1" );

Fig. 11.24 | Huge integers. (Part 1 of 2.)


2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

21

22
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
n1
n2
n3
n4
n5

Chapter 11 Operator Overloading; String and Array Objects

HugeInt n5;
cout << "n1 is " << n1 << "\nn2 is " << n2
<< "\nn3 is " << n3 << "\nn4 is " << n4
<< "\nn5 is " << n5 << "\n\n";
n5 = n1 + n2;
cout << n1 << " + " << n2 << " = " << n5 << "\n\n";
cout << n3 << " + " << n4 << "\n= " << ( n3 + n4 ) << "\n\n";
n5 = n1 + 9;
cout << n1 << " + " << 9 << " = " << n5 << "\n\n";
n5 = n2 + "10000";
cout << n2 << " + " << "10000" << " = " << n5 << endl;
return 0;
} // end main
is
is
is
is
is

7654321
7891234
99999999999999999999999999999
1
0

7654321 + 7891234 = 15545555


99999999999999999999999999999 + 1
= 100000000000000000000000000000
7654321 + 9 = 7654330
7891234 + 10000 = 7901234

Fig. 11.24 | Huge integers. (Part 2 of 2.)


ANS: [Note: This solution, as it is based on the code above, does not handle negative values,

or cases when a value causes overflow. Also, the solution overloads the - operator, but
this is not necessarystudents need to implement subtraction of HugeInts to implement division, but they can use a private helper function if they wish.]

1
2
3
4
5
6
7
8
9

// Fig. 11.22: Hugeint.h


// HugeInt class definition.
#ifndef HUGEINT_H
#define HUGEINT_H
#include <iostream>
using std::ostream;
class HugeInt

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

1
2
3
4
5
6
7
8
9
10
11
12
13
14

// Fig. 11.23: Hugeint.cpp


// HugeInt member-function and friend-function definitions.
#include <iostream>
using std::cout;
using std::endl;

23

friend ostream &operator<<( ostream &, const HugeInt & );


public:
HugeInt( long = 0 ); // conversion/default constructor
HugeInt( const char * ); // conversion constructor
// addition operator; HugeInt + HugeInt
HugeInt operator+( const HugeInt & ) const;
// addition operator; HugeInt + int
HugeInt operator+( int ) const;
// addition operator;
// HugeInt + string that represents large integer value
HugeInt operator+( const char * ) const;
bool operator==( const HugeInt & ) const; // equality operator
bool operator!=( const HugeInt & ) const; // inequality operator
bool operator<( const HugeInt & ) const; // less than operator
// less than or equal to operator
bool operator<=( const HugeInt & ) const;
bool operator>( const HugeInt & ) const; // greater than operator
// greater than or equal to operator
bool operator>=( const HugeInt & ) const;
HugeInt operator-( const HugeInt & ) const; // subtraction operator
HugeInt operator*( const HugeInt & ) const; // multiply two HugeInts
HugeInt operator/( const HugeInt & ) const; // divide two HugeInts
int getLength() const;
private:
short integer[ 30 ];
}; // end class HugeInt
#endif

#include <cctype> // isdigit function prototype


using std::isdigit;
#include <cstring> // strlen function prototype
using std::strlen;
#include "Hugeint.h" // HugeInt class definition

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

24
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

Chapter 11 Operator Overloading; String and Array Objects

// default constructor; conversion constructor that converts


// a long integer into a HugeInt object
HugeInt::HugeInt( long value )
{
// initialize array to zero
for ( int i = 0; i <= 29; i++ )
integer[ i ] = 0;
// place digits of argument into array
for ( int j = 29; value != 0 && j >= 0; j-- )
{
integer[ j ] = value % 10;
value /= 10;
} // end for
} // end HugeInt default/conversion constructor
// conversion constructor that converts a character string
// representing a large integer into a HugeInt object
HugeInt::HugeInt( const char *string )
{
// initialize array to zero
for ( int i = 0; i <= 29; i++ )
integer[ i ] = 0;
// place digits of argument into array
int length = strlen( string );
for ( int j = 30 - length, k = 0; j <= 29; j++, k++ )
if ( isdigit( string[ k ] ) )
integer[ j ] = string[ k ] - '0';
} // end HugeInt conversion constructor
// get function calculates length of integer
int HugeInt::getLength() const
{
for ( int i = 0; i <= 29; i++ )
if ( integer[ i ] != 0 )
break; // break when first digit is reached
return 30 - i; // length is from first digit (at i) to end of array
} // end function getLength
// addition operator; HugeInt + HugeInt
HugeInt HugeInt::operator+( const HugeInt &op2 ) const
{
HugeInt temp; // temporary result
int carry = 0;
for ( int i = 29; i >= 0; i-- )
{
temp.integer[ i ] =
integer[ i ] + op2.integer[ i ] + carry;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

// determine whether to carry a 1


if ( temp.integer[ i ] > 9 )
{
temp.integer[ i ] %= 10; // reduce to 0-9
carry = 1;
} // end if
else // no carry
carry = 0;
} // end for
return temp; // return copy of temporary object
} // end function operator+
// addition operator; HugeInt + int
HugeInt HugeInt::operator+( int op2 ) const
{
// convert op2 to a HugeInt, then invoke
// operator+ for two HugeInt objects
return *this + HugeInt( op2 );
} // end function operator+
// addition operator;
// HugeInt + string that represents large integer value
HugeInt HugeInt::operator+( const char *op2 ) const
{
// convert op2 to a HugeInt, then invoke
// operator+ for two HugeInt objects
return *this + HugeInt( op2 );
} // end function operator+
// equality operator; HugeInt == HugeInt
bool HugeInt::operator==( const HugeInt &op2 ) const
{
for ( int i = 0; i < 30; i++ ) // compare each element
if ( op2.integer[ i ] != integer[ i ] )
return false; // return false if mismatch found
return true; // all elements match, return true
} // end function operator==
// inequality operator; HugeInt != HugeInt
bool HugeInt::operator!=( const HugeInt &op2 ) const
{
return !( *this == op2 ); // return opposite of ==
} // end function operator!=
// less than operator; HugeInt < HugeInt
bool HugeInt::operator<( const HugeInt &op2 ) const
{
for ( int i = 0; i < 30; i++ ) // compare each element
{
if ( integer[ i ] == op2.integer[ i ] )
continue; // test next element

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

25

26
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

Chapter 11 Operator Overloading; String and Array Objects

else if ( integer[ i ] > op2.integer[ i ] )


return false; // first element larger
else
return true; // first element smaller
} // end for
return false; // if reached this point, objects are equal
} // end function operator<
// less than or equal operator; HugeInt <= HugeInt
bool HugeInt::operator<=( const HugeInt &op2 ) const
{
return ( ( *this == op2 ) || ( *this < op2 ) );
} // end function operator<=
// greater than operator; HugeInt > HugeInt
bool HugeInt::operator>( const HugeInt &op2 ) const
{
return !( *this <= op2 );
} // end function operator>
// greater than or equal operator; HugeInt >= HugeInt
bool HugeInt::operator>=( const HugeInt &op2 ) const
{
return ( ( *this == op2 ) || ( *this > op2 ) );
} // end function operator>=
// overloaded output operator
ostream& operator<<( ostream &output, const HugeInt &num )
{
int i;
for ( i = 0; ( num.integer[ i ] == 0 ) && ( i <= 29 ); i++ )
; // skip leading zeros
if ( i == 30 )
output << 0;
else
for ( ; i <= 29; i++ )
output << num.integer[ i ];
return output;
} // end function operator<<
// subtraction operator, subtract op2 from (*this)
HugeInt HugeInt::operator-( const HugeInt &op2 ) const
{
// return if first value is smaller; we are not handling negatives
if ( op2 > ( *this ) )
{
cout << "Error: Tried to subtract larger value from smaller value."
<< endl;
return HugeInt( "0" );

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230

27

} // end if
HugeInt result( "0" ); // final result currently 0
// used to determine if previous digit had 10 added to it;
// if true, current digit needs to be reduced by 1
bool minusOne = false;
// for each digit in both arrays,
// subtract digit of smaller int from digit of larger int
for ( int i = 29; i >= 0; i-- )
{
// find digits we will currently be subtracting
int topValue = ( *this ).integer[ i ];
int bottomValue = op2.integer[ i ];
// if previous topValue had 10 added to it;
// subtract one from current topValue
if ( minusOne )
{
if ( topValue == 0 ) // topValue cannot become -1
// set to 9 but keep minusOne true for next digit
topValue = 9;
else
{
topValue -= 1; // subtract from top value
minusOne = false; // minusOne is handled, return to false
} // end else
} // end outer if
if ( topValue >= bottomValue )
// if topValue larger, perform subtraction and store result
result.integer[ i ] = topValue - bottomValue;
else
{
topValue += 10; // if bottomValue larger, add 10 to topValue
minusOne = true; // next digit must be decreased
// topValue is now larger, perform subtraction and store result
result.integer[ i ] = topValue - bottomValue;
} // end else
} // end for
return result; // return final result
} // end function operator// multiplication operator; multiply op2 with (*this)
HugeInt HugeInt::operator*( const HugeInt &op2 ) const
{
int carryOver = 0; // carry value when previous digits are multiplied
HugeInt total( "0" ); // result currently 0

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

28
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284

Chapter 11 Operator Overloading; String and Array Objects

// find the smaller int


HugeInt smaller = ( *this < op2 ) ? *this : op2;
HugeInt larger = ( *this > op2 ) ? *this : op2;
// determine index of larger's first digit; used to determine
// when to stop multiplying
for ( int x = 0; ( x <= 29 ) && ( larger.integer[ x ] == 0 ); x++ ) ;
int indexOfFirstDigitForLarger = x;
// for each digit in smaller, multiply by each digit in larger
for ( int i = 30; i > 30 - smaller.getLength(); i-- )
{
// currentInt stores result of current digit in
// smaller multiplied by digits in larger
HugeInt currentInt( "0" );
// currentIntFrontHandle used to keep track of
// index of first digit in currentInt
int currentIntFrontHandle = i - 1;
// multiply each digit in larger with the current digit in smaller;
// go backwards from last digit in larger to first digit
for ( int j = 30; j > 30 - larger.getLength(); j-- )
{
// perform multiplication;
// add carryOver from previous multiplications
int currentResult = carryOver +
( larger.integer[ j - 1 ] * smaller.integer[ i - 1 ] );
// if we have reached the first digit of larger
if ( j - 1 == indexOfFirstDigitForLarger )
{
carryOver = 0; // no more carryOver required
// store two digits at beginning of currentInt, update handle
currentInt.integer[ currentIntFrontHandle ] =
currentResult % 10;
currentIntFrontHandle -= 1;
currentInt.integer[ currentIntFrontHandle ] =
currentResult / 10;
currentIntFrontHandle -= 1;
} // end if
else
{
// carryOver is first digit when currentResult > 10
carryOver = currentResult / 10;
// store remaining digit in current result; update handle
currentInt.integer[ currentIntFrontHandle ] =
currentResult % 10;
currentIntFrontHandle -= 1;
} // end else
} // end inner for

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338

29

total = total + currentInt; // add current result to running total


} // end outer for
return total; // return product
} // end function operator*
// division operator; divide op2 by (*this)
HugeInt HugeInt::operator/( const HugeInt &op2 ) const
{
// use copy constructor to create remainderIntegers;
// remainderIntegers used to add digits to remainders
HugeInt remainderIntegers( *this );
// contains portion of (*this)
HugeInt currentValue( "0" );
HugeInt result( "0" ); // final result, 0 for now
// solution will not be longer than original value being divided
int maxSolutionLength = ( *this ).getLength();
// for each digit in value being divided
for ( int i = 30 - maxSolutionLength; i < 30; i++ )
{
// add remainder to end of current value
currentValue = currentValue * HugeInt( "10" );
currentValue.integer[ 29 ] = remainderIntegers.integer[ i ];
HugeInt tempResult( "0" ); // result of currentValue divided by op2
if ( op2 > currentValue )
// store result of op2 / currentValue
result.integer[ i ] = 0;
else
{
// op2 / currentValue cannot be greater than 9;
// use loop to determine what solution is
for ( int j = 1; j <= 10; j++ )
{
HugeInt tempProduct = op2 * HugeInt( j );
// if op2 * HugeInt( j ) is greater than currentValue,
// then op2 / currentValue is the value of j - 1
if ( tempProduct > currentValue )
break;
} // end for
result.integer[ i ] = j - 1; // result of op2 / currentValue
// product used to determine next value that must be divided
tempResult = op2 * HugeInt( j - 1 );
} // end else
// subtract tempResult to get remainder used to continue division

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

30

Chapter 11 Operator Overloading; String and Array Objects

339
currentValue = currentValue - tempResult;
340
} // end for
341
342
return result;
343 } // end function operator/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

// Exercise 11.14 Solution: ex11_14.cpp


// HugeInt test program.
#include <iostream>
using std::cout;
using std::endl;
#include "Hugeint.h"
int main()
{
HugeInt
HugeInt
HugeInt
HugeInt
HugeInt
HugeInt
HugeInt

n1( 7654321 );
n2( 7891234 );
n3( "99999999999999999999999999999" );
n4( "1" );
n5( "12341234" );
n6( "7888" );
result;

cout << "n1 is " << n1 << "\nn2 is " << n2


<< "\nn3 is " << n3 << "\nn4 is " << n4
<< "\nn5 is " << n5 << "\nn6 is " << n6
<< "\nresult is " << result << "\n\n";
// test relational and equality operators
if ( n1 == n2 )
cout << "n1 equals n2" << endl;
if ( n1 != n2 )
cout << "n1 is not equal to n2" << endl;
if ( n1 < n2 )
cout << "n1 is less than n2" << endl;
if ( n1 <= n2 )
cout << "n1 is less than or equal to n2" << endl;
if ( n1 > n2 )
cout << "n1 is greater than n2" << endl;
if ( n1 >= n2 )
cout << "n1 is greater than or equal to n2" << endl;
result = n1 + n2;
cout << n1 << " + " << n2 << " = " << result << "\n\n";

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

31

cout << n3 << " + " << n4 << "\n= " << ( n3 + n4 ) << "\n\n";
result = n1 + 9;
cout << n1 << " + " << 9 << " = " << result << endl;
result = n2 + "10000";
cout << n2 << " + " << "10000" << " = " << result << endl;
result = n5 * n6;
cout << n5 << " * " << n6 << " = " << result << endl;
result = n5 - n6;
cout << n5 << " - " << n6 << " = " << result << endl;
result = n5 / n6;
cout << n5 << " / " << n6 << " = " << result << endl;
return 0;
} // end main

n1 is 7654321
n2 is 7891234
n3 is 99999999999999999999999999999
n4 is 1
n5 is 12341234
n6 is 7888
result is 0
n1 is not equal to n2
n1 is less than n2
n1 is less than or equal to n2
7654321 + 7891234 = 15545555
99999999999999999999999999999 + 1
= 100000000000000000000000000000
7654321 + 9 = 7654330
7891234 + 10000 = 7901234
12341234 * 7888 = 97347653792
12341234 - 7888 = 12333346
12341234 / 7888 = 1564

11.15 Create a class RationalNumber (fractions) with the following capabilities:


a) Create a constructor that prevents a 0 denominator in a fraction, reduces or simplifies
fractions that are not in reduced form and avoids negative denominators.
b) Overload the addition, subtraction, multiplication and division operators for this class.
c) Overload the relational and equality operators for this class.
ANS:

1
2

// Exercise 11.15 Solution: RationalNumber.h


// RationalNumber class definition.

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

32

Chapter 11 Operator Overloading; String and Array Objects

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

#ifndef RATIONAL_NUMBER_H
#define RATIONAL_NUMBER_H

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

// Exercise 11.15 Solution: RationalNumber.cpp


// RationalNumber member-function definitions.
#include <cstdlib>
using std::exit;

class RationalNumber
{
public:
RationalNumber( int = 0, int = 1 ); // default constructor
RationalNumber operator+( const RationalNumber& ); // addition
RationalNumber operator-( const RationalNumber& ); // subtraction
RationalNumber operator*( const RationalNumber& ); // multiplication
RationalNumber operator/( RationalNumber& ); // division
// relational operators
bool operator>( const RationalNumber& ) const;
bool operator<( const RationalNumber& ) const;
bool operator>=( const RationalNumber& ) const;
bool operator<=( const RationalNumber& ) const;
// equality operators
bool operator==( const RationalNumber& ) const;
bool operator!=( const RationalNumber& ) const;
void printRational() const; // display rational number
private:
int numerator; // private variable numerator
int denominator; // private variable denominator
void reduction(); // function for fraction reduction
}; // end class RationalNumber
#endif

#include <iostream>
using std::cout;
using std::endl;
#include "RationalNumber.h"
// RationalNumber constructor sets n and d and calls reduction
RationalNumber::RationalNumber( int n, int d )
{
numerator = n;
denominator = ( d > 0 ) ? d : 1; // validate denominator, 1 as default
reduction(); // invokes function reduction
} // end RationalNumber constructor
// overloaded + operator
RationalNumber RationalNumber::operator+( const RationalNumber &a )
{

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

return RationalNumber(
numerator * a.denominator + denominator * a.numerator,
denominator * a.denominator );
} // end function operator+
// overloaded - operator
RationalNumber RationalNumber::operator-( const RationalNumber &s )
{
return RationalNumber(
numerator * s.denominator - denominator * s.numerator,
denominator * s.denominator );
} // end function operator// overloaded * operator
RationalNumber RationalNumber::operator*( const RationalNumber &m )
{
return RationalNumber( numerator * m.numerator,
denominator * m.denominator );
} // end function operator*
// overloaded / operator
RationalNumber RationalNumber::operator/( RationalNumber &d )
{
RationalNumber divide;
if ( d.numerator != 0 ) // check for a zero in numerator
{
return RationalNumber( numerator * d.denominator,
denominator * d.numerator );
}
else
{
cout << "Divide by zero error: terminating program" << endl;
exit( 1 ); // stdlib function
} // end if/else structure
} // end function operator/
// overloaded > operator
bool RationalNumber::operator>( const RationalNumber &gr ) const
{
if ( static_cast< double >( numerator ) / denominator >
static_cast< double >( gr.numerator ) / gr.denominator )
return true;
else
return false;
} // end function operator>
// overloaded < operator
bool RationalNumber::operator<( const RationalNumber &lr ) const
{
if ( static_cast< double >( numerator ) / denominator <
static_cast< double >( lr.numerator ) / lr.denominator )
return true;
else

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

33

34
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

Chapter 11 Operator Overloading; String and Array Objects

return false;
} // end function operator<
// overloaded >= operator
bool RationalNumber::operator>=( const RationalNumber &ger ) const
{
return *this == ger || *this > ger;
} // end function operator>=
// overloaded <= operator
bool RationalNumber::operator<=( const RationalNumber &ler ) const
{

return *this == ler || *this < ler;


} // end function operator<=
// overloaded == operator
bool RationalNumber::operator==( const RationalNumber &er ) const
{
if ( numerator == er.numerator && denominator == er.denominator )
return true;
else
return false;
} // end function operator==
// overloaded != operator
bool RationalNumber::operator!=( const RationalNumber &ner ) const
{
return !( *this == ner );
} // end function operator!=
// function printRational definition
void RationalNumber::printRational() const
{
if ( numerator == 0 ) // print fraction as zero
cout << numerator;
else if ( denominator == 1 ) // print fraction as integer
cout << numerator;
else
cout << numerator << '/' << denominator;
} // end function printRational
// function reduction definition
void RationalNumber::reduction()
{
int largest, gcd = 1; // greatest common divisor;
largest = ( numerator > denominator ) ? numerator: denominator;
for ( int loop = 2; loop <= largest; loop++ )
if ( numerator % loop == 0 && denominator % loop == 0 )
gcd = loop;
numerator /= gcd;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
131
denominator /= gcd;
132 } // end function reduction
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

// Exercise 11.15 Solution: ex11_15.cpp


// RationalNumber test program.
#include <iostream>
using std::cout;
using std::endl;
#include "RationalNumber.h"
int main()
{
RationalNumber c( 7, 3 ), d( 3, 9 ), x;
c.printRational();
cout << " + " ;
d.printRational();
cout << " = ";
x = c + d; // test overloaded operators + and =
x.printRational();
cout << '\n';
c.printRational();
cout << " - " ;
d.printRational();
cout << " = ";
x = c - d; // test overloaded operators - and =
x.printRational();
cout << '\n';
c.printRational();
cout << " * " ;
d.printRational();
cout << " = ";
x = c * d; // test overloaded operators * and =
x.printRational();
cout << '\n';
c.printRational();
cout << " / " ;
d.printRational();
cout << " = ";
x = c / d; // test overloaded operators / and =
x.printRational();
cout << '\n';
c.printRational();
cout << " is:\n";
// test overloaded greater than operator
cout << ( ( c > d ) ? " > " : " <= " );
d.printRational();

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

35

36
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

Chapter 11 Operator Overloading; String and Array Objects

cout << " according to the overloaded > operator\n";


// test overloaded less than operator
cout << ( ( c < d ) ? " < " : " >= " );
d.printRational();
cout << " according to the overloaded < operator\n";
// test overloaded greater than or equal to operator
cout << ( ( c >= d ) ? " >= " : " < " );
d.printRational();
cout << " according to the overloaded >= operator\n";
// test overloaded less than or equal to operator
cout << ( ( c <= d ) ? " <= " : " > " );
d.printRational();
cout << " according to the overloaded <= operator\n";
// test overloaded equality operator
cout << ( ( c == d ) ? " == " : " != " );
d.printRational();
cout << " according to the overloaded == operator\n";
// test overloaded inequality operator
cout << ( ( c != d ) ? " != " : " == " );
d.printRational();
cout << " according to the overloaded != operator" << endl;
return 0;
} // end main

7/3 + 1/3 = 8/3


7/3 - 1/3 = 2
7/3 * 1/3 = 7/9
7/3 / 1/3 = 7
7/3 is:
> 1/3 according to the overloaded > operator
>= 1/3 according to the overloaded < operator
>= 1/3 according to the overloaded >= operator
> 1/3 according to the overloaded <= operator
!= 1/3 according to the overloaded == operator
!= 1/3 according to the overloaded != operator

11.16 Study the C string-handling library functions and implement each of the functions as part
of class String (Figs. 11.911.10). Then, use these functions to perform text manipulations.
11.17 Develop class Polynomial. The internal representation of a Polynomial is an array of terms.
Each term contains a coefficient and an exponent. The term
2x4
has the coefcient 2 and the exponent 4. Develop a complete class containing proper constructor
and destructor functions as well as set and get functions. The class should also provide the following
overloaded operator capabilities:
a) Overload the addition operator (+) to add two Polynomials.
b) Overload the subtraction operator (-) to subtract two Polynomials.

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions

37

c) Overload the assignment operator to assign one Polynomial to another.


d) Overload the multiplication operator (*) to multiply two Polynomials.
e) Overload the addition assignment operator (+=), subtraction assignment operator (-=),
and multiplication assignment operator (*=).
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

// Exercise 11.17 Solution: Polynomial.h


// Polynomial class definition.
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H

1
2
3
4
5
6
7
8
9
10
11
12
13
14

// Exercise 11.17 Solution: Polynomial.cpp


// Polynomial member-function definitions.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;

class Polynomial
{
public:
Polynomial();
Polynomial operator+( const Polynomial& ) const; // addition
Polynomial operator-( const Polynomial& ) const; // subtraction
Polynomial operator*( const Polynomial& ); // multiplication
const Polynomial operator=( const Polynomial& ); // assignment
Polynomial& operator+=( const Polynomial& );
Polynomial& operator-=( const Polynomial& );
Polynomial& operator*=( const Polynomial& );
void enterTerms();
void printPolynomial() const;
int getNumberOfTerms(); // user should only be able to retrieve value
int getTermExponent( int );
int getTermCoefficient( int );
void setCoefficient( int, int ); // set coefficient of a specific term
~Polynomial(); // destructor
private:
int numberOfTerms;
int exponents[ 100 ]; // exponent array
int coefficients[ 100 ]; // coefficients array
void polynomialCombine( Polynomial& ); // combine common terms
}; // end class Polynomial
#endif

#include <iomanip>
using std::showpos;
using std::noshowpos;
#include "Polynomial.h"
Polynomial::Polynomial()

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

38
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

Chapter 11 Operator Overloading; String and Array Objects

for ( int t = 0; t < 100; t++ )


{
coefficients[ t ] = 0;
exponents[ t ] = 0;
} // end for

numberOfTerms = 0;
} // end Polynomial constructor
void Polynomial::printPolynomial() const
{
int start;
bool zero = false;
if ( coefficients[ 0 ] ) // output constants
{
cout << coefficients[ 0 ];
start = 1;
zero = true; // at least one term exists
}
else
{
if ( coefficients[ 1 ] )
{
cout << coefficients[ 1 ] << 'x'; // constant does not exist
// so output first term
// without a sign
if ( ( exponents[ 1 ] != 0 ) && ( exponents[ 1 ] != 1 ) )
cout << '^' << exponents[ 1 ];
zero = true; // at least one term exists
} // end inner if
start = 2;
} // end else
// output remaining polynomial terms
for ( int x = start; x < 100; x++ )
{
if ( coefficients[ x ] != 0 )
{
cout << showpos << coefficients[ x ] << noshowpos << 'x';
if ( ( exponents[ x ] != 0 ) && ( exponents[ x ] != 1 ) )
cout << '^' << exponents[ x ];
zero = true;
} // end if
} // end for

// at least one term exists

if ( !zero ) // no terms exist in the polynomial


cout << '0';

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

cout << endl;


} // end function printPolynomial
const Polynomial Polynomial::operator=( const Polynomial& r )
{
exponents[ 0 ] = r.exponents[ 0 ];
coefficients[ 0 ] = r.coefficients[ 0 ];
for ( int s = 1; ( s < 100 ); s++ )
{
if ( r.exponents[ s ] != 0 )
{
exponents[ s ] = r.exponents[ s ];
coefficients[ s ] = r.coefficients[ s ];
}
else
{
if ( exponents[ s ] == 0 )
break;
exponents[ s ] = 0;
coefficients[ s ] = 0;
} // end else
} // end for
return *this;
} // end function operator=
Polynomial Polynomial::operator+( const Polynomial& r ) const
{
Polynomial temp;
bool exponentExists;
int s;
// process element with a zero exponent
temp.coefficients[ 0 ] = coefficients[ 0 ] + r.coefficients[ 0 ];
// copy right arrays into temp object s will be used to keep
// track of first open coefficient element
for ( s = 1; ( s < 100 ) && ( r.exponents[ s ] != 0 ); s++ )
{
temp.coefficients[ s ] = r.coefficients[ s ];
temp.exponents[ s ] = r.exponents[ s ];
} // end for
for ( int x = 1; x < 100; x++ )
{
exponentExists = false; // assume exponent will not be found
for ( int t = 1; ( t < 100 ) && ( !exponentExists ); t++ )
if ( exponents[ x ] == temp.exponents[ t ] )
{
temp.coefficients[ t ] += coefficients[ x ];

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

39

40
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

Chapter 11 Operator Overloading; String and Array Objects

exponentExists = true;
} // end if

// exponent found

// exponent was not found, insert into temp


if ( !exponentExists )
{
temp.exponents[ s ] = exponents[ x ];
temp.coefficients[ s ] += coefficients[ x ];
s++;
} // end if
} // end for
return temp;
} // end function operator+
Polynomial &Polynomial::operator+=( const Polynomial &r )
{
*this = *this + r;
return *this;
} // end function operator+=
Polynomial Polynomial::operator-( const Polynomial& r ) const
{
Polynomial temp;
bool exponentExists;
int s;
// process element with a zero exponent
temp.coefficients[ 0 ] = coefficients[ 0 ] - r.coefficients[ 0 ];
// copy left arrays into temp object s will be used to keep
// track of first open coefficient element
for ( s = 1; ( s < 100 ) && ( exponents[ s ] != 0 ); s++ )
{
temp.coefficients[ s ] = coefficients[ s ];
temp.exponents[ s ] = exponents[ s ];
} // end for
for ( int x = 1; x < 100; x++ )
{
exponentExists = false; // assume exponent will not be found
for ( int t = 1; ( t < 100 ) && ( !exponentExists ); t++ )
if ( r.exponents[ x ] == temp.exponents[ t ] )
{
temp.coefficients[ t ] -= r.coefficients[ x ];
exponentExists = true; // exponent found
} // end if
// exponent was not found, insert into temp
if ( !exponentExists )
{
temp.exponents[ s ] = r.exponents[ x ];

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230

41

temp.coefficients[ s ] -= r.coefficients[ x ];
s++;
} // end if
} // end for
return temp;
} // end function operatorPolynomial &Polynomial::operator-=( const Polynomial& r )
{
*this = *this - r;
return *this;
} // end function operator-=
Polynomial Polynomial::operator*( const Polynomial& r )
{
Polynomial temp;
int s = 1; // subscript location for temp coefficient and exponent
for ( int x = 0; ( x < 100 ) &&
( x == 0 || coefficients[ x ] != 0 ); x++ )
for ( int y = 0; ( y < 100 ) &&
( y == 0 || r.coefficients[ y ] != 0 ); y++ )
if ( coefficients[ x ] * r.coefficients[ y ] )
if ( ( exponents[ x ] == 0 ) && ( r.exponents[ y ] == 0 ) )
temp.coefficients[ 0 ] +=
coefficients[ x ] * r.coefficients[ y ];
else
{
temp.coefficients[ s ] =
coefficients[ x ] * r.coefficients[ y ];
temp.exponents[ s ] = exponents[ x ] + r.exponents[ y ];
s++;
} // end else
polynomialCombine( temp ); // combine common terms
return temp;
} // end function operator*
void Polynomial::polynomialCombine( Polynomial& w )
{
Polynomial temp = w;
int exp;
// zero out elements of w
for ( int x = 0; x < 100; x++ )
{
w.coefficients[ x ] = 0;
w.exponents[ x ] = 0;
} // end for

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

42
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284

Chapter 11 Operator Overloading; String and Array Objects

for ( int x = 1; x < 100; x++ )


{
exp = temp.exponents[ x ];
for ( int y = x + 1; y < 100; y++ )
if ( exp == temp.exponents[ y ] )
{
temp.coefficients[ x ] += temp.coefficients[ y ];
temp.exponents[ y ] = 0;
temp.coefficients[ y ] = 0;
} // end if
} // end outer for
w = temp;
} // end function polynomialCombine
Polynomial &Polynomial::operator*=( const Polynomial& r )
{
*this = *this * r;
return *this;
} // end function operator*=
void Polynomial::enterTerms()
{
bool found = false;
int c, e, term;
cout << "\nEnter number of polynomial terms: ";
cin >> numberOfTerms;
for ( int n = 1; n <= numberOfTerms; n++ )
{
cout << "\nEnter coefficient: ";
cin >> c;
cout << "Enter exponent: ";
cin >> e;
if ( c != 0 )
{
// exponents of zero are forced into first element
if ( e == 0 )
{
coefficients[ 0 ] += c;
continue;
} // end if
for ( term = 1; ( term < 100 ) &&
( coefficients[ term ] != 0 ); term++ )
if ( e == exponents[ term ] )
{
coefficients[ term ] += c;
exponents[ term ] = e;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
1
2
3
4
5
6
7
8
9
10
11
12

found = true;
} // end if

// existing exponent updated

if ( !found ) // add term


{
coefficients[ term ] += c;
exponents[ term ] = e;
} // end if
} // end outer if
} // end outer for
} // end function endTerms
int Polynomial::getNumberOfTerms()
{
return numberOfTerms;
} // end function getNumberOfTerms
int Polynomial::getTermExponent( int term )
{
return exponents[ term ];
} // end function getTermExponent
int Polynomial::getTermCoefficient( int term )
{
return coefficients[ term ];
} // end function getTermsCoefficient
void Polynomial::setCoefficient( int term, int coefficient )
{
if ( coefficients[ term ] == 0 ) // no term at this location
cout << "No term at this location, cannot set term." << endl;
else // otherwise, set term
coefficients[ term ] = coefficient;
} // end function setTerm
// destructor
Polynomial::~Polynomial()
{
// empty destructor
} // end destructor

// Exercise 11.17 Solution: ex11_17.cpp


// Polynomial test program.
#include <iostream>
using std::cout;
using std::endl;
#include "Polynomial.h"
int main()
{
Polynomial a, b, c, t;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

43

44
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

Chapter 11 Operator Overloading; String and Array Objects

a.enterTerms();
b.enterTerms();
t = a;
// save the value of a
cout << "First polynomial is:\n";
a.printPolynomial();
cout << "Second polynomial is:\n";
b.printPolynomial();
cout << "\nAdding the polynomials yields:\n";
c = a + b;
c.printPolynomial();
cout << "\n+= the polynomials yields:\n";
a += b;
a.printPolynomial();
cout << "\nSubtracting the polynomials yields:\n";
a = t; // reset a to original value
c = a - b;
c.printPolynomial();
cout << "\n-= the polynomials yields:\n";
a -= b;
a.printPolynomial();
cout << "\nMultiplying the polynomials yields:\n";
a = t; // reset a to original value
c = a * b;
c.printPolynomial();
cout << "\n*= the polynomials yields:\n";
a *= b;
a.printPolynomial();
cout << endl;
return 0;
} // end main

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions

45

Enter number of polynomial terms: 2


Enter coefficient: 2
Enter exponent: 2
Enter coefficient: 3
Enter exponent: 3
Enter number of polynomial terms: 3
Enter coefficient: 1
Enter exponent: 1
Enter coefficient: 2
Enter exponent: 2
Enter coefficient: 3
Enter exponent: 3
First polynomial is:
2x^2+3x^3
Second polynomial is:
1x+2x^2+3x^3
Adding the polynomials yields:
1x+4x^2+6x^3
+= the polynomials yields:
1x+4x^2+6x^3
Subtracting the polynomials yields:
-1x
-= the polynomials yields:
-1x
Multiplying the polynomials yields:
2x^3+7x^4+12x^5+9x^6
*= the polynomials yields:
2x^3+7x^4+12x^5+9x^6

11.18 In the program of Figs. 11.311.5, Fig. 11.4 contains the comment overloaded

stream

insertion operator; cannot be a member function if we would like to invoke it with cout <<

somePhoneNumber;.

Actually, the stream insertion operator could be a PhoneNumber class member


function if we were willing to invoke it either as somePhoneNumber.operator<<( cout ); or as somePhoneNumber << cout;. Rewrite the program of Fig. 11.5 with the overloaded stream insertion operator<< as a member function and try the two preceding statements in the program to demonstrate
that they work.
ANS:

1
2
3

// Exercise 11.18 Solution: PhoneNumber.h


// PhoneNumber class definition
#ifndef PHONENUMBER_H

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

46

Chapter 11 Operator Overloading; String and Array Objects

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

#define PHONENUMBER_H

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

// Exercise 11.18 Solution: PhoneNumber.cpp


// Overloaded stream insertion and stream extraction operators
// for class PhoneNumber.
#include <iomanip>
using std::setw;

#include <iostream>
using std::ostream;
using std::istream;
#include <string>
using std::string;
class PhoneNumber
{
friend istream &operator>>( istream &, PhoneNumber & );
public:
ostream &operator<<( ostream &output );
private:
string areaCode; // 3-digit area code
string exchange; // 3-digit exchange
string line; // 4-digit line
}; // end class PhoneNumber
#endif

#include "PhoneNumber.h"
// overloaded stream insertion operator; cannot be
// a member function if we would like to invoke it with
// cout << somePhoneNumber;
ostream &PhoneNumber::operator<<( ostream &output )
{
output << "(" << areaCode << ") " << exchange << "-" << line;
return output; // enables cout << a << b << c;
} // end function operator<<
// overloaded stream extraction operator; cannot be
// a member function if we would like to invoke it with
// cin >> somePhoneNumber;
istream &operator>>( istream &input, PhoneNumber &number )
{
input.ignore(); // skip (
input >> setw( 3 ) >> number.areaCode; // input area code
input.ignore( 2 ); // skip ) and space
input >> setw( 3 ) >> number.exchange; // input exchange
input.ignore(); // skip dash (-)
input >> setw( 4 ) >> number.line; // input line
return input; // enables cin >> a >> b >> c;
} // end function operator>>

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

// Exercise 11.18 Solution: ex11_18.cpp


// Demonstrating class PhoneNumber's overloaded stream insertion
// and stream extraction operators.
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
#include "PhoneNumber.h"
int main()
{
PhoneNumber phone; // create object phone
cout << "Enter phone number in the form (123) 456-7890:" << endl;
// cin >> phone invokes operator>> by implicitly issuing
// the global function call operator>>( cin, phone )
cin >> phone;
cout << "The phone number entered was: ";
// cout << phone invokes operator<< by implicitly issuing
// the global function call operator<<( cout, phone )
phone.operator << ( cout ) << endl;
return 0;
} // end main

Enter phone number in the form (123) 456-7890:


(800) 555-1212
The phone number entered was: (800) 555-1212

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

47