Title: Operator Overloading
1Operator Overloading
- Operator overloading like function overloading is
another feature of C polymorphism - Programmer can use some operator symbols to
define special member functions of class - Operators provide programmers with a concise
notation for expressing manipulations of objects
of built-in types. - Operators introduced for overloading should make
either conventional or meaningful.
2Operator Overloading
- Why we need to have operator overloading?
- Make convenient to use in object operation.
- Example
Can we do this?
int a5,b6, c cab
int ida1002, idb1003 int
Idc100 idcidaidb
What about this?
for (j0jlt100j) idcjidajidbj
3Operator Overloading
- Can we make object operation look like individual
int variable operation, such as ab? For example
two objects are added together. - Answer is Yes!. We can use operator function to
perform it.
Time a,b,c cab
4Operator Overloading
- Valid operator symbols
- Not valid operator symbols
- / ! lt gt - /
ltlt gtgt gtgt ltlt ! lt gt -- -gt -gt
() new delete new delete
. . ? sizeof
5Operator Overloading
- Syntax is
- Example Time class's object manipulation
operatorop (argument-list)
--- operator is a function
--- op is one of Coperator symbols
6ifndef _MYTIME0_H_ define _MYTIME0_H_ includelti
ostream.hgt class Time private int hours
int minutes
7Operator Overloading
public Time() Time(int h, int m0)
void addMin(int m) void addHr(int h)
void reset(int h0, int m0) Time sum(const
Time t) const void show() const endif
8Operator Overloading
// mytime0.cpp --- implement Time
methods include "mytime0.h" TimeTime()
hoursminutes0 Time Time(int h, int m)
hoursh minutesm void TimeaddMin(int m)
minutes m hoursminutes/60 minutes
60
9Operator Overloading
void TimeaddHr(int h) hoursh void
Timereset(int h, int m) hoursh
minutesm
10Operator Overloading
Time Timesum(const Time t) const Time
sum sum.minutesminutest.minutes
sum.hourshourst.hourssum.minutes/60
sum.minutes 60 return sum
11Operator Overloading
void Timeshow() const coutltlthoursltlt"
hours, "ltltminutesltlt " minutes" coutltlt
'\n'
12Operator Overloading
//use mytime0.cpp use first draft of Time
class //compile usemytime0.cpp and mytime0.cpp
together include ltiostream.hgt include
"mytime0.h" int main() Time A Time
B(5,40) Time C(2,55)
13Operator Overloading
A.show() B.show() C.show()
AB.sum(C) A.show() return 0 0 hours,
0 minutes 5 hours, 40 minutes 2 hours, 55
minutes 8 hours, 35 minutes
Looks not comfortable, when a object adds to
another object. Can we modify it?
14Operator Overloading
// mytime1.h Time class after operator
overloading ifndef _MYTIME1_H_ define
_MYTIME1_H_ includeltiostream.hgt class
Time private int hours int minutes
15Operator Overloading
public Time() Time(int h, int m0)
void addMin(int m) void addHr(int h)
void reset(int h0, int m0) Time
operator(const Time t) const void show()
const endif
We add another function named as operator
16Operator Overloading
// mytime1.cpp --- implement Time
methods include "mytime1.h" TimeTime()
hoursminutes0 Time Time(int h, int m)
hoursh minutesm void TimeaddMin(int m)
minutes m hoursminutes/60
minutes 60
17Operator Overloading
void TimeAddHr(int h) hoursh void
TimeReset(int h, int m) hoursh
minutesm
18Operator Overloading
Time Timeoperator(const Time t) const
Time sum sum.minutesminutest.minutes
sum.hourshourst.hourssum.minutes/60
sum.minutes 60 return sum void
Timeshow() const coutltlthoursltlt" hours,
"ltltminutesltlt " minutes" coutltlt '\n'
19Operator Overloading
//use mytime1.cpp use second draft of Time
class //compile usemytime1.cpp and mytime1.cpp
together include ltiostream.hgt include
"mytime1.h" int main() Time A Time
B(5,40) Time C(2,55)
20Operator Overloading
A.show() B.show() C.show()
AB.operator(C) //function notation
A.show() BAC // operator notation
B.show() return 0
Result
A
0 hours, 0 minutes 5 hours, 40 minutes 2 hours,
55 minutes 8 hours, 35 minutes 11 hours, 30
minutes
B
C
ABC
BAC
21Operator Overloading
//mytime2.h // mytime2.h Time class after
operator overloading ifndef _MYTIME2_H_ define
_MYTIME2_H_ includeltiostream.hgt class
Time private int hours int
minutes public Time() Time(int h, int
m0)
22Operator Overloading
void addMin(int m) void addHr(int h)
void reset(int h0, int m0) Time
operator(const Time t) const Time
operator-(const Time t) const Time
operator(double mult) const void show()
const endif
23Operator Overloading
// mytime2.cpp --- implement Time
methods include "mytime2.h" TimeTime()
hoursminutes0 Time Time(int h, int m)
hoursh minutesm
24Operator Overloading
void TimeaddMin(int m) minutes m
hoursminutes/60 minutes 60 void
TimeaddHr(int h) hoursh
25void Timereset(int h, int m) hoursh
minutesm Time Timeoperator(const Time
t) const Time sum sum.minutesminutest
.minutes sum.hourshourst.hourssum.minutes/
60 sum.minutes 60 return sum
26Operator Overloading
Time Timeoperator-(const Time t) const
Time diff int tot1, tot2
tot1t.minutes60t.hours tot2minutes60hou
rs diff.minutes(tot2-tot1)60
diff.hours(tot2-tot1)/60 return diff
27Operator Overloading
Time Timeoperator(double mult) const Time
result long totalminuteshoursmult60
minutesmult result.minutestotalminutes60
result.hourstotalminutes/60 return
result void Timeshow() const
coutltlthoursltlt" hours, "ltltminutesltlt " minutes"
coutltlt '\n'
28Operator Overloading
//use mytime2.cpp use third draft of Time
class //compile usemytime2.cpp and mytime2.cpp
together include ltiostream.hgt include
"mytime2.h" int main() Time A Time
B(5,40) Time C(2,55)
29Operator Overloading
A.Show() B.Show() C.Show() ABC
// operator() A.show() AB-C //
operator-() A.show() AB2.75 //
operator() which is equivalent to 2.75B
A.show() return 0
How to avoid this, so we have 2.75B or B2.75 ?
30Operator Overloading
- In order to solve this problem, we can introduce
a non-member - function, but a friend function of class Time.
- Now let look at the following modified
declaration of Time class, - which includes a friend function.
31Operator Overloading
// mytime3.h Time class with friends ifndef
_MYTIME3_H_ define _MYTIME3_H_ includeltiostream.
hgt class Time private int hours int
minutes public Time() Time(int h, int
m0)
32Operator Overloading
void addMin(int m) void addHr(int h)
void reset(int h0, int m0) Time
operator(const Time t) const Time
operator-(const Time t) const Time
operator(double n) const friend Time
operator(double m, const Time t)
return tm // inline definition void
show() const endif
33Operator Overloading
// mytime3.cpp --- implement Time
methods include "mytime3.h" TimeTime()
hoursminutes0 Time Time(int h, int m)
hoursh minutesm
34Operator Overloading
void TimeaddMin(int m) minutes m
hoursminutes/60 minutes 60 void
TimeaddHr(int h) hoursh
35Operator Overloading
void Timereset(int h, int m) hoursh
minutesm Time Timeoperator(const Time t)
const Time sum sum.minutesminutest.mi
nutes sum.hourshourst.hourssum.minutes/60
sum.minutes 60 return sum
36Operator Overloading
Time Timeoperator-(const Time t) const
Time diff int tot1, tot2
tot1t.minutes60t.hours tot2minutes60hou
rs diff.minutes(tot2-tot1)60
diff.hours(tot2-tot1)/60 return diff
37Operator Overloading
Time Timeoperator(double mult) const
Time result long totalminuteshoursmult60
minutesmult result.minutestotalminutes60
result.hourstotalminutes/60 return
result void Timeshow() const
coutltlthoursltlt" hours, "ltltminutesltlt " minutes"
coutltlt '\n'
38Operator Overloading
include ltiostream.hgt include "mytime3a.h" int
main() Time A Time B(5,40) Time
C(2,55)
39Operator Overloading
A.show() B.show() C.show() ABC
// operator() A.show() AB2.75 //
use member operator() A.show() A10.23B
// use friend function A.show() return
0
Can we use coutltlt to print out object, such as
coutltltAltltBltltC ?
Result
0 hours, 0 minutes 5 hours, 40 minutes 2 hours,
55 minutes 8 hours, 35 minutes 15 hours, 35
minutes 57 hours, 58 minutes
40Operator Overloading
ABC // operator() AB.operator(C)
member function Aoperator(B,C) non-member
function
41Operator Overloading
- Yes! In fact coutltlt or cingtgt are operator
overloading built in - C standard lib of iostream.h using operator
"ltlt" and "gtgt" - cout and cin are the objects of ostream and
istream - classes, respectively.
- We can add a friend function which overload the
- operator ltlt.
cout ---- object of ostream
ostream operatorltlt(ostream os, const Time
t) osltltt.hoursltlt" hours, "ltltt.minutesltlt"
minutes" return os
42// mytime3.h Time class with friends ifndef
_MYTIME3_H_ define _MYTIME3_H_ includeltiostream.
hgt class Time private int hours int
minutes public Time() Time(int h, int
m0) void addMin(int m) void addHr(int
h) void reset(int h0, int m0)
43 Time operator(const Time t) const Time
operator-(const Time t) const Time
operator(double n) const friend Time
operator(double m, const Time t)
return tm // inline definition friend
ostream operatorltlt(ostream os, const Time
t) endif
44// mytime3.cpp --- implement Time
methods include "mytime3.h" TimeTime()
hoursminutes0 Time Time(int h, int m)
hoursh minutesm void TimeaddMin(int m)
minutes m hoursminutes/60 minutes
60 void TimeaddHr(int h) hoursh
void Timereset(int h, int m) hoursh
minutesm
45Time Timeoperator(const Time t)
const mytime3.cpp END Time sum
sum.minutesminutest.minutes
sum.hourshourst.hourssum.minutes/60
sum.minutes 60 return sum Time
Timeoperator-(const Time t) const Time
diff int tot1, tot2 tot1t.minutes60t.
hours tot2minutes60hours
diff.minutes(tot2-tot1)60
diff.hours(tot2-tot1)/60 return diff
46Time Timeoperator(double mult) const
Time result long totalminuteshoursmult60
minutesmult result.minutestotalminutes60
result.hourstotalminutes/60 return
result ostream operatorltlt(ostream os,
const Time t) osltltt.hoursltlt" hours,
"ltltt.minutesltlt" minutes" return os
47//use mytime3.cpp use fourth draft of Time
class //compile usemytime3.cpp and mytime3.cpp
together include ltiostream.hgt include
"mytime3.h" int main() Time A Time
B(5,40) Time C(2,55) coutltltAltlt" "ltltBltlt"
"ltltCltltendl ABC // operator()
coutltltAltltendl AB2.75 // use member
operator() coutltltAltltendl A10.23B //
use friend function coutltltAltltendl return
0
480 hours, 0 minutes 5 hours, 40 minutes 2 hours,
55 minutes 8 hours, 35 minutes 15 hours, 35
minutes 57 hours, 58 minutes
49Operator functions as class members vs. friend
functions
- Operator functions can be member functions or
non-member-functions, made by friend functions - member function uses "this" implicitly to stands
for the invoked object. - all of the objects participate in the non-member
function should be through the arguments - Example
50Operator functions as class members vs. friend
functions
Rational r1new Rational(2.3) Rational r1new
Rational(3,7) r1.add(r2)
// member function of Rational class add(r1,r2)
//non-member function How
about operator functions to overload these "add"
functions?
51Overloading stream-insertion (ltlt) and
stream-extraction (gtgt) operators
- Overloaded in C library already for built-in
data type - It can also be overloaded for user defined data
type - Example
52// Fig. 8.3 fig08_03.cpp // Overloading the
stream-insertion and // stream-extraction
operators. include ltiostreamgt using
stdcout using stdcin using stdendl using
stdostream using stdistream include
ltiomanipgt using stdsetw
53class PhoneNumber friend ostream
operatorltlt( ostream, const PhoneNumber )
friend istream operatorgtgt( istream, PhoneNumber
) private char areaCode 4 // 3-digit
area code and null char exchange 4 //
3-digit exchange and null char line 5
// 4-digit line and null // Overloaded
stream-insertion operator (cannot be // a member
function if we would like to invoke it with //
cout ltlt somePhoneNumber). ostream operatorltlt(
ostream output, const PhoneNumber num )
output ltlt "(" ltlt num.areaCode ltlt ") "
ltlt num.exchange ltlt "-" ltlt num.line return
output // enables cout ltlt a ltlt b ltlt c
54istream operatorgtgt( istream input, PhoneNumber
num ) input.ignore()
// skip ( input gtgt setw( 4 ) gtgt num.areaCode
// input area code input.ignore( 2 )
// skip ) and space input gtgt setw( 4 )
gtgt num.exchange // input exchange
input.ignore() // skip dash
(-) input gtgt setw( 5 ) gtgt num.line //
input line return input // enables cin
gtgt a gtgt b gtgt c
55int main() PhoneNumber phone // create
object phone cout ltlt "Enter phone number in
the form (123) 456-7890\n" // cin gtgt phone
invokes operatorgtgt function by // issuing the
call operatorgtgt( cin, phone ). cin gtgt phone
// cout ltlt phone invokes operatorltlt function
by // issuing the call operatorltlt( cout, phone
). cout ltlt "The phone number entered was "
ltlt phone ltlt endl return 0
56Enter phone number in the form (123)
456-7890 (319) 335-5486 The phone number entered
was (319) 335-5486
57Overloading Unary Operators
- A unary operator for a class can be overload as a
non-static member function with no argument or as
a non-member function with one argument - Example
58class String public bool operator!()
const class String public friend
bool operator!(const String )
59// Fig. 8.4 array1.h // Simple class Array (for
integers) ifndef ARRAY1_H define
ARRAY1_H include ltiostreamgt using
stdostream using stdistream class Array
friend ostream operatorltlt( ostream , const
Array ) friend istream operatorgtgt( istream
, Array ) public Array( int 10 )
// default constructor Array(
const Array ) // copy constructor
60 Array() //
destructor int getSize() const
// return size const Array operator( const
Array ) // assign arrays bool operator(
const Array ) const // compare equal //
Determine if two arrays are not equal and //
return true, otherwise return false (uses
operator). bool operator!( const Array
right ) const return ! ( this
right ) int operator( int )
// subscript operator const int
operator( int ) const // subscript operator
static int getArrayCount() // Return
count of
// arrays instantiated.
61private int size // size of the array int
ptr // pointer to first element of array
static int arrayCount // of Arrays
instantiated endif
62// Fig 8.4 array1.cpp // Member function
definitions for class Array include
ltiostreamgt using stdcout using
stdcin using stdendl include
ltiomanipgt using stdsetw include
ltcstdlibgt include ltcassertgt include "array1.h"
63// Initialize static data member at file
scope int ArrayarrayCount 0 // no objects
yet // Default constructor for class Array
(default size 10) ArrayArray( int arraySize
) size ( arraySize gt 0 ? arraySize 10 )
ptr new int size // create space for
array assert( ptr ! 0 ) // terminate if
memory not allocated arrayCount //
count one more object for ( int i 0 i lt
size i ) ptr i 0 //
initialize array
64// Copy constructor for class Array // must
receive a reference to prevent infinite
recursion ArrayArray( const Array init )
size( init.size ) ptr new int size //
create space for array assert( ptr ! 0 )
// terminate if memory not allocated
arrayCount // count one more object
for ( int i 0 i lt size i ) ptr i
init.ptr i // copy init into object
65// Destructor for class Array ArrayArray()
delete ptr // reclaim space for
array --arrayCount // one fewer
objects // Get the size of the array int
ArraygetSize() const return size //
Overloaded assignment operator // const return
avoids ( a1 a2 ) a3 const Array
Arrayoperator( const Array right ) if (
right ! this ) // check for self-assignment
66 // for arrays of different sizes,
deallocate original // left side array,
then allocate new left side array. if (
size ! right.size ) delete ptr
// reclaim space size right.size
// resize this object ptr new int
size // create space for array copy
assert( ptr ! 0 ) // terminate if not
allocated for ( int i 0 i lt
size i ) ptr i right.ptr i
// copy array into object return this
// enables x y z
67 // Determine if two arrays are equal and //
return true, otherwise return false. bool
Arrayoperator( const Array right ) const
if ( size ! right.size ) return false
// arrays of different sizes for ( int i 0
i lt size i ) if ( ptr i ! right.ptr
i ) return false // arrays are not
equal return true // arrays are
equal
68// Overloaded subscript operator for non-const
Arrays // reference return creates an lvalue int
Arrayoperator( int subscript ) // check
for subscript out of range error assert( 0 lt
subscript subscript lt size ) return ptr
subscript // reference return // Overloaded
subscript operator for const Arrays // const
reference return creates an rvalue const int
Arrayoperator( int subscript ) const //
check for subscript out of range error assert(
0 lt subscript subscript lt size )
69 return ptr subscript // const reference
return // Return the number of Array objects
instantiated // static functions cannot be const
int ArraygetArrayCount() return arrayCount
// Overloaded input operator for class
Array // inputs values for entire array. istream
operatorgtgt( istream input, Array a ) for
( int i 0 i lt a.size i ) input gtgt
a.ptr i return input // enables cin gtgt
x gtgt y
70// Overloaded output operator for class Array
ostream operatorltlt( ostream output, const
Array a ) int i for ( i 0 i lt
a.size i ) output ltlt setw( 12 ) ltlt
a.ptr i if ( ( i 1 ) 4 0 ) // 4
numbers per row of output output ltlt
endl if ( i 4 ! 0 ) output ltlt
endl return output // enables cout ltlt x
ltlt y
71// Fig. 8.4 fig08_04.cpp // Driver for simple
class Array include ltiostreamgt using
stdcout using stdcin using
stdendl include "array1.h" int main()
// no objects yet cout ltlt " of arrays
instantiated " ltlt ArraygetArrayCount()
ltlt '\n'
72 // create two arrays and print Array count
Array integers1( 7 ), integers2 cout ltlt " of
arrays instantiated " ltlt
ArraygetArrayCount() ltlt "\n\n" // print
integers1 size and contents cout ltlt "Size of
array integers1 is " ltlt
integers1.getSize() ltlt "\nArray after
initialization\n" ltlt integers1 ltlt
'\n' // print integers2 size and contents
cout ltlt "Size of array integers2 is " ltlt
integers2.getSize() ltlt "\nArray after
initialization\n" ltlt integers2 ltlt '\n'
73 // input and print integers1 and integers2
cout ltlt "Input 17 integers\n" cin gtgt
integers1 gtgt integers2 cout ltlt "After input,
the arrays contain\n" ltlt "integers1\n"
ltlt integers1 ltlt "integers2\n" ltlt
integers2 ltlt '\n' // use overloaded
inequality (!) operator cout ltlt "Evaluating
integers1 ! integers2\n" if ( integers1 !
integers2 ) cout ltlt "They are not
equal\n" // create array integers3 using
integers1 as an // initializer print size and
contents Array integers3( integers1 )
74 cout ltlt "\nSize of array integers3 is "
ltlt integers3.getSize() ltlt "\nArray
after initialization\n" ltlt integers3 ltlt
'\n' // use overloaded assignment ()
operator cout ltlt "Assigning integers2 to
integers1\n" integers1 integers2 cout
ltlt "integers1\n" ltlt integers1 ltlt
"integers2\n" ltlt integers2 ltlt '\n' // use
overloaded equality () operator cout ltlt
"Evaluating integers1 integers2\n" if (
integers1 integers2 ) cout ltlt "They are
equal\n\n"
75 // use overloaded subscript operator to
create rvalue cout ltlt "integers15 is " ltlt
integers1 5 ltlt '\n' // use overloaded
subscript operator to create lvalue cout ltlt
"Assigning 1000 to integers15\n" integers1
5 1000 cout ltlt "integers1\n" ltlt
integers1 ltlt '\n' // attempt to use out of
range subscript cout ltlt "Attempt to assign
1000 to integers115" ltlt endl integers1 15
1000 // ERROR out of range return 0
76// Fig. 8.5 string1.h // Definition of a String
class ifndef STRING1_H define
STRING1_H include ltiostreamgt using
stdostream using stdistream class String
friend ostream operatorltlt( ostream , const
String ) friend istream operatorgtgt(
istream , String ) public String( const
char "" ) // conversion/default ctor
77 String( const String ) // copy
constructor String() //
destructor const String operator( const
String ) // assignment const String
operator( const String ) // concatenation
bool operator!() const // is
String empty? bool operator( const String
) const // test s1 s2 bool operatorlt(
const String ) const // test s1 lt s2 //
test s1 ! s2 bool operator!( const String
right ) const return !( this right )
// test s1 gt s2 bool operatorgt( const
String right ) const return right lt
this
78 // test s1 lt s2 bool operatorlt( const
String right ) const return !( right lt
this ) // test s1 gt s2 bool
operatorgt( const String right ) const
return !( this lt right ) char operator(
int ) // subscript operator const
char operator( int ) const // subscript
operator String operator()( int, int )
// return a substring int getLength() const
// return string length private
int length // string length
char sPtr // pointer to
start of string void setString( const char
) // utility function endif
79// Fig. 8.5 string1.cpp // Member function
definitions for class String include
ltiostreamgt using stdcout using
stdendl include ltiomanipgt using
stdsetw include ltcstringgt include
ltcassertgt include "string1.h"
80// Conversion constructor Convert char to
String StringString( const char s ) length(
strlen( s ) ) cout ltlt "Conversion
constructor " ltlt s ltlt '\n' setString( s )
// call utility function // Copy
constructor StringString( const String copy )
length( copy.length ) cout ltlt "Copy
constructor " ltlt copy.sPtr ltlt '\n'
setString( copy.sPtr ) // call utility
function
81// Destructor StringString() cout ltlt
"Destructor " ltlt sPtr ltlt '\n' delete
sPtr // reclaim string // Overloaded
operator avoids self assignment const String
Stringoperator( const String right )
cout ltlt "operator called\n" if ( right !
this ) // avoid self assignment
delete sPtr // prevents memory
leak length right.length // new
String length setString( right.sPtr )
// call utility function
82 else cout ltlt "Attempted assignment of a
String to itself\n" return this //
enables cascaded assignments // Concatenate
right operand to this object and // store in this
object. const String Stringoperator( const
String right ) char tempPtr sPtr
// hold to be able to delete length
right.length // new String length sPtr
new char length 1 // create space
assert( sPtr ! 0 ) // terminate if memory not
allocated strcpy( sPtr, tempPtr ) // left
part of new String strcat( sPtr, right.sPtr )
// right part of new String
83 delete tempPtr // reclaim old
space return this // enables
cascaded calls // Is this String empty? bool
Stringoperator!() const return length 0
// Is this String equal to right String? bool
Stringoperator( const String right ) const
return strcmp( sPtr, right.sPtr ) 0 //
Is this String less than right String? bool
Stringoperatorlt( const String right ) const
return strcmp( sPtr, right.sPtr ) lt 0
84// Return a reference to a character in a String
as an lvalue. char Stringoperator( int
subscript ) // First test for subscript out
of range assert( subscript gt 0 subscript lt
length ) return sPtr subscript //
creates lvalue // Return a reference to a
character in a String as an rvalue. const char
Stringoperator( int subscript ) const
// First test for subscript out of range
assert( subscript gt 0 subscript lt length )
return sPtr subscript // creates rvalue
85// Return a substring beginning at index and //
of length subLength String Stringoperator()(
int index, int subLength ) // ensure index
is in range and substring length gt 0 assert(
index gt 0 index lt length subLength gt 0
) // determine length of substring int
len if ( ( subLength 0 ) ( index
subLength gt length ) ) len length -
index else len subLength
86 // allocate temporary array for substring and
// terminating null character char tempPtr
new char len 1 assert( tempPtr ! 0 )
// ensure space allocated // copy substring
into char array and terminate string strncpy(
tempPtr, sPtr index , len ) tempPtr len
'\0' // Create temporary String object
containing the substring String tempString(
tempPtr ) delete tempPtr // delete the
temporary array return tempString // return
copy of the temporary String
87// Return string length int StringgetLength()
const return length // Utility function to
be called by constructors and // assignment
operator. void StringsetString( const char
string2 ) sPtr new char length 1 //
allocate storage assert( sPtr ! 0 ) //
terminate if memory not allocated strcpy(
sPtr, string2 ) // copy literal to
object // Overloaded output operator ostream
operatorltlt( ostream output, const String s
) output ltlt s.sPtr return output //
enables cascading
88 // Overloaded input operator istream
operatorgtgt( istream input, String s )
char temp 100 // buffer to store input
input gtgt setw( 100 ) gtgt temp s temp
// use String class assignment operator return
input // enables cascading
89// Fig. 8.5 fig08_05.cpp // Driver for class
String include ltiostreamgt using
stdcout using stdendl include
"string1.h" int main() String s1( "happy"
), s2( " birthday" ), s3 // test overloaded
equality and relational operators cout ltlt "s1
is \"" ltlt s1 ltlt "\" s2 is \"" ltlt s2 ltlt
"\" s3 is \"" ltlt s3 ltlt '\"' ltlt "\nThe
results of comparing s2 and s1"
90 ltlt "\ns2 s1 yields " ltlt ( s2 s1 ?
"true" "false" ) ltlt "\ns2 ! s1 yields
" ltlt ( s2 ! s1 ? "true" "false" )
ltlt "\ns2 gt s1 yields " ltlt ( s2 gt s1
? "true" "false" ) ltlt "\ns2 lt s1
yields " ltlt ( s2 lt s1 ? "true" "false"
) ltlt "\ns2 gt s1 yields " ltlt (
s2 gt s1 ? "true" "false" ) ltlt "\ns2 lt
s1 yields " ltlt ( s2 lt s1 ? "true"
"false" ) // test overloaded String empty
(!) operator cout ltlt "\n\nTesting !s3\n"
91if ( !s3 ) cout ltlt "s3 is empty
assigning s1 to s3\n" s3 s1
// test overloaded assignment cout ltlt "s3
is \"" ltlt s3 ltlt "\"" // test overloaded
String concatenation operator cout ltlt "\n\ns1
s2 yields s1 " s1 s2
// test overloaded concatenation cout ltlt s1
// test conversion constructor cout ltlt
"\n\ns1 \" to you\" yields\n" s1 " to
you" // test conversion constructor
cout ltlt "s1 " ltlt s1 ltlt "\n\n"
92// test overloaded function call operator () for
substring cout ltlt "The substring of s1
starting at\n" ltlt "location 0 for 14
characters, s1(0, 14), is\n" ltlt s1( 0,
14 ) ltlt "\n\n" // test substring
"to-end-of-String" option cout ltlt "The
substring of s1 starting at\n" ltlt
"location 15, s1(15, 0), is " ltlt s1( 15,
0 ) ltlt "\n\n" // 0 is "to end of string" //
test copy constructor String s4Ptr new
String( s1 ) cout ltlt "s4Ptr " ltlt s4Ptr
ltlt "\n\n" // test assignment () operator
with self-assignment cout ltlt "assigning s4Ptr
to s4Ptr\n" s4Ptr s4Ptr //
test overloaded assignment
93 cout ltlt "s4Ptr " ltlt s4Ptr ltlt '\n' //
test destructor delete s4Ptr // test
using subscript operator to create lvalue s1
0 'H' s1 6 'B' cout ltlt
"\ns1 after s10 'H' and s16 'B' is "
ltlt s1 ltlt "\n\n" // test subscript out of
range cout ltlt "Attempt to assign 'd' to s130
yields" ltlt endl s1 30 'd' //
ERROR subscript out of range return 0
94Overloading and --
95// Fig. 8.6 date1.h // Definition of class
Date ifndef DATE1_H define DATE1_H include
ltiostreamgt using stdostream class Date
friend ostream operatorltlt( ostream , const Date
) public Date( int m 1, int d 1, int
y 1900 ) // constructor void setDate( int,
int, int ) // set the date Date
operator() // preincrement
operator Date operator( int ) //
postincrement operator
96 const Date operator( int ) // add days,
modify object bool leapYear( int ) const
// is this a leap year? bool endOfMonth( int )
const // is this end of month? private int
month int day int year static const
int days // array of days per month
void helpIncrement() // utility
function endif
97// Fig. 8.6 date1.cpp // Member function
definitions for Date class include
ltiostreamgt include "date1.h" // Initialize
static member at file scope // one class-wide
copy. const int Datedays 0, 31, 28, 31,
30, 31, 30, 31, 31,
30, 31, 30, 31 // Date constructor DateDate(
int m, int d, int y ) setDate( m, d, y )
98// Set the date void DatesetDate( int mm, int
dd, int yy ) month ( mm gt 1 mm lt 12 )
? mm 1 year ( yy gt 1900 yy lt 2100 )
? yy 1900 // test for a leap year if (
month 2 leapYear( year ) ) day ( dd
gt 1 dd lt 29 ) ? dd 1 else day
( dd gt 1 dd lt days month ) ? dd 1
99// Preincrement operator overloaded as a member
function. Date Dateoperator()
helpIncrement() return this // reference
return to create an lvalue // Postincrement
operator overloaded as a member function. // Note
that the dummy integer parameter does not have
a // parameter name. Date Dateoperator( int
) Date temp this helpIncrement()
// return non-incremented, saved, temporary
object return temp // value return not a
reference return
100// Add a specific number of days to a date const
Date Dateoperator( int additionalDays )
for ( int i 0 i lt additionalDays i )
helpIncrement() return this // enables
cascading // If the year is a leap year, return
true // otherwise, return false bool
DateleapYear( int y ) const if ( y 400
0 ( y 100 ! 0 y 4 0 ) )
return true // a leap year else
return false // not a leap year
101// Determine if the day is the end of the
month bool DateendOfMonth( int d ) const
if ( month 2 leapYear( year ) )
return d 29 // last day of Feb. in leap year
else return d days month //
Function to help increment the date void
DatehelpIncrement() if ( endOfMonth( day )
month 12 ) // end year day 1
month 1 year
102else if ( endOfMonth( day ) ) // end
month day 1 month else
// not end of month or year increment day
day // Overloaded output
operator ostream operatorltlt( ostream output,
const Date d ) static char monthName 13
"", "January", "February", "March",
"April", "May", "June", "July", "August",
"September", "October", "November",
"December" output ltlt monthName d.month
ltlt ' 'ltlt d.day ltlt ", " ltlt d.year return
output // enables cascading
103// Fig. 8.6 fig08_06.cpp // Driver for class
Date include ltiostreamgt using stdcout using
stdendl include "date1.h" int main()
Date d1, d2( 12, 27, 1992 ), d3( 0, 99, 8045 )
cout ltlt "d1 is " ltlt d1 ltlt "\nd2 is " ltlt
d2 ltlt "\nd3 is " ltlt d3 ltlt "\n\n"
cout ltlt "d2 7 is " ltlt ( d2 7 ) ltlt "\n\n"
104 d3.setDate( 2, 28, 1992 ) cout ltlt " d3
is " ltlt d3 cout ltlt "\nd3 is " ltlt d3 ltlt
"\n\n" Date d4( 3, 18, 1969 ) cout ltlt
"Testing the preincrement operator\n" ltlt
" d4 is " ltlt d4 ltlt '\n' cout ltlt "d4 is "
ltlt d4 ltlt '\n' cout ltlt " d4 is " ltlt d4 ltlt
"\n\n" cout ltlt "Testing the postincrement
operator\n" ltlt " d4 is " ltlt d4 ltlt
'\n' cout ltlt "d4 is " ltlt d4 ltlt '\n'
cout ltlt " d4 is " ltlt d4 ltlt endl return 0
105// Fig. 8.7 complex1.h // Definition of class
Complex ifndef COMPLEX1_H define
COMPLEX1_H class Complex public Complex(
double 0.0, double 0.0 ) //
constructor Complex operator( const Complex
) const // addition Complex operator-( const
Complex ) const // subtraction const
Complex operator( const Complex ) //
assignment void print() const
// output private double real
// real part double imaginary // imaginary
part endif
106// Fig. 8.7 complex1.cpp // Member function
definitions for class Complex include
ltiostreamgt using stdcout include
"complex1.h" // Constructor ComplexComplex(
double r, double i ) real( r ), imaginary(
i ) // Overloaded addition operator Complex
Complexoperator( const Complex operand2 )
const return Complex( real operand2.real,
imaginary
operand2.imaginary )
107// Overloaded subtraction operator Complex
Complexoperator-( const Complex operand2 )
const return Complex( real - operand2.real,
imaginary -
operand2.imaginary ) // Overloaded
operator const Complex Complexoperator( const
Complex right ) real right.real
imaginary right.imaginary return this
// enables cascading // Display a Complex
object in the form (a, b) void Complexprint()
const cout ltlt '(' ltlt real ltlt ", " ltlt
imaginary ltlt ')'
108// Fig. 8.7 fig08_07.cpp // Driver for class
Complex include ltiostreamgt using
stdcout using stdendl include
"complex1.h" int main() Complex x, y( 4.3,
8.2 ), z( 3.3, 1.1 ) cout ltlt "x "
x.print() cout ltlt "\ny " y.print()
109 cout ltlt "\nz " z.print() x y z
cout ltlt "\n\nx y z\n" x.print() cout
ltlt " " y.print() cout ltlt " "
z.print() x y - z cout ltlt "\n\nx y -
z\n" x.print() cout ltlt " "
y.print() cout ltlt " - " z.print()
cout ltlt endl return 0
110 cout ltlt "\nz " z.print() x y z
cout ltlt "\n\nx y z\n" x.print() cout
ltlt " " y.print() cout ltlt " "
z.print() x y - z cout ltlt "\n\nx y -
z\n" x.print() cout ltlt " "
y.print() cout ltlt " - " z.print()
cout ltlt endl
return 0
111// Fig. 8.8 hugeint1.h // Definition for class
HugeInt ifndef HUGEINT1_H define
HUGEINT1_H include ltiostreamgt using
stdostream class HugeInt friend ostream
operatorltlt( ostream , const HugeInt
) public HugeInt( long 0 ) //
conversion/default constructor HugeInt( const
char ) // conversion constructor
HugeInt operator( const HugeInt ) // add
another HugeInt HugeInt operator( int )
// add an int HugeInt operator( const
char ) // add an int in a char private
short integer 30 endif
112// Fig. 8.8 hugeint1.cpp // Member and friend
function definitions for class HugeInt include
ltcstringgt include "hugeint1.h" // Conversion
constructor HugeIntHugeInt( long val ) int
i for ( i 0 i lt 29 i )
integer i 0 // initialize array to zero
for ( i 29 val ! 0 i gt 0 i-- )
integer i val 10 val / 10
113 HugeIntHugeInt( const char string ) int
i, j for ( i 0 i lt 29 i )
integer i 0 for ( i 30 - strlen(
string ), j 0 i lt 29 i, j ) if (
isdigit( string j ) ) integer i
string j - '0' // Addition HugeInt
HugeIntoperator( const HugeInt op2 )
HugeInt temp
114 int carry 0 for ( int i 29 i gt 0 i--
) temp.integer i integer i
op2.integer i carry
if ( temp.integer i gt 9 )
temp.integer i 10 carry 1
else carry 0 return
temp
115// Addition HugeInt HugeIntoperator( int op2
) return this HugeInt( op2 ) //
Addition HugeInt HugeIntoperator( const char
op2 ) return this HugeInt( op2 )
ostream operatorltlt( ostream output, const
HugeInt num ) int i for ( i 0 (
num.integer i 0 ) ( i lt 29 ) i )
// skip leading zeros
116 if ( i 30 ) output ltlt 0 else
for ( i lt 29 i ) output ltlt
num.integer i return output
117// Fig. 8.8 fig08_08.cpp // Test driver for
HugeInt class include ltiostreamgt using
stdcout using stdendl include
"hugeint1.h" int main() HugeInt n1( 7654321
), n2( 7891234 ), n3(
"99999999999999999999999999999" ), n4(
"1" ), n5 cout ltlt "n1 is " ltlt n1 ltlt "\nn2 is
" ltlt n2 ltlt "\nn3 is " ltlt n3 ltlt "\nn4 is "
ltlt n4 ltlt "\nn5 is " ltlt n5 ltlt "\n\n"
118 n5 n1 n2 cout ltlt n1 ltlt " " ltlt n2 ltlt
" " ltlt n5 ltlt "\n\n" cout ltlt n3 ltlt " " ltlt
n4 ltlt "\n " ltlt ( n3 n4 ) ltlt "\n\n"
n5 n1 9 cout ltlt n1 ltlt " " ltlt 9 ltlt "
" ltlt n5 ltlt "\n\n" n5 n2 "10000" cout
ltlt n2 ltlt " " ltlt "10000" ltlt " " ltlt n5 ltlt
endl return 0