0% found this document useful (0 votes)
61 views

Lec6. Operator Overload

The document discusses overloading operators for a Money class. It defines operators like +, -, and == to work with Money objects. It also covers returning objects from functions and overloading unary operators like - to change the sign of a Money amount.

Uploaded by

Majd AL Kawaas
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
61 views

Lec6. Operator Overload

The document discusses overloading operators for a Money class. It defines operators like +, -, and == to work with Money objects. It also covers returning objects from functions and overloading unary operators like - to change the sign of a Money amount.

Uploaded by

Majd AL Kawaas
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 28

Chapter 8

Operator
Overloading, Friends,

and References

Copyright © 2017 Pearson Education, Ltd.


All rights reserved.
Operator Overloading Introduction
• Built-in operators +, -, %, ==, /, *, etc.
– Really just functions!
– Already work for C++ built-in types
• Simply "called" with different syntax: x + 7 instead of +(x, 7)
– "+" is binary operator with x & 7 as operands
– We "like" this notation as humans
• We can overload them! to work with OUR classes/types!
• Overloading operators is VERY similar to overloading functions
– Operator itself is "name" of function

Example Declaration:
const Money operator +(const Money& amount1, const Money& amount2);
– Overloads + for operands of type Money
– Uses constant reference parameters for efficiency
– Returned value is type Money that is the addition of "Money" objects
8-2
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
//Class for amounts of money in U.S. currency
class Money {
public:
Money( );
Money( double amount);
Money( int theDollars, int theCents);
Money( int theDollars);
double getAmount( ) const {return (dollars + cents*0.01);}
int getDollars( ) const {return dollars;}
int getCents( ) const {return cents;}
void input( ); //Reads the dollar sign as well as the amount number.
void output( ) const;
private:
int dollars; //A negative amount is represented as negative dollars and
int cents; //negative cents. Negative $4.50 is represented as -4 and -50.
int dollarsPart( double amount) const {return static_cast<int>(amount); }
int centsPart( double amount) const;
int round( double number) const{return static_cast<int>(floor(number + 0.5));}
};
const Money operator +( const Money& amount1, const Money& amount2);
const Money operator -( const Money& amount1, const Money& amount2);
bool operator ==( const Money& amount1, const Money& amount2);
8-3
const Money operator -( const Money& amount);
int main( ){
Money yourAmount, myAmount(10, 9);
cout << "Enter an amount of money: ";
yourAmount.input( );
cout << "Your amount is "; Enter an amount of money: $123.45
yourAmount.output( ); Your amount is $123.45
cout << endl;
My amount is $10.09.
cout << "My amount is ";
One of us is richer.
myAmount.output( );
cout << endl;
$123.45 + $10.09 equals $133.54
if (yourAmount == myAmount) $123.45 - $10.09 equals $113.36
cout << "We have the same amounts.\n";
else
cout << "One of us is richer.\n";
Money ourAmount = yourAmount + myAmount;
yourAmount.output( ); cout << " + "; myAmount.output( );
cout << " equals "; ourAmount.output(); cout << endl;
return 0;
}
Money::Money( ): dollars(0), cents(0)
{ /*Body intentionally empty.*/}
Money::Money(double amount):dollars(dollarsPart(amount)), cents(centsPart(amount))
{ /*Body intentionally empty*/ }
Money::Money( int theDollars): dollars(theDollars), cents(0)
{ /*Body intentionally empty*/}

8-4
Money::Money( int theDollars, int theCents){
if ((theDollars < 0 && theCents > 0) ||(theDollars > 0 && theCents < 0)){
cout << "Inconsistent money data.\n";
exit(1);
}
dollars = theDollars;
cents = theCents;
}
int Money::centsPart( double amount) const{
double doubleCents = amount * 100;
int intCents = (round(fabs(doubleCents))) % 100;
if (amount < 0) //% can misbehave on negatives
intCents = -intCents;
return intCents;
}
const Money operator +( const Money& amount1, const Money& amount2){
int allCents1 = amount1.getCents( ) + amount1.getDollars( )*100;
int allCents2 = amount2.getCents( ) + amount2.getDollars( )*100;
int sumAllCents = allCents1 + allCents2;
int absAllCents = abs(sumAllCents); //Money can be negative.
int finalDollars = absAllCents / 100;
int finalCents = absAllCents % 100;
if (sumAllCents < 0){
finalDollars = -finalDollars;
finalCents = -finalCents;
}
return Money(finalDollars, finalCents);
} 8-5
const Money operator -( const Money& amount1, const Money& amount2){
int allCents1 = amount1.getCents( ) + amount1.getDollars( )*100;
int allCents2 = amount2.getCents( ) + amount2.getDollars( )*100;
int diffAllCents = allCents1 - allCents2;
int absAllCents = abs(diffAllCents);
int finalDollars = absAllCents / 100;
int finalCents = absAllCents % 100;
if (diffAllCents < 0) {
finalDollars = -finalDollars;
finalCents = -finalCents;
}
return Money(finalDollars, finalCents);
}
bool operator ==( const Money& amount1, const Money& amount2) {
return ((amount1.getDollars( ) == amount2.getDollars( ))
&& (amount1.getCents( ) == amount2.getCents( )));
}
const Money operator -( const Money& amount) {
return Money(-amount.getDollars( ), -amount.getCents( ));
}

8-6
void Money::output( ) const {
int absDollars = abs(dollars);
int absCents = abs(cents);
if (dollars < 0 || cents < 0) //accounts for dollars == 0 or cents == 0
cout << "$-";
else
cout << '$';
cout << absDollars;

if (absCents >= 10)


cout << '.' << absCents;
else
cout << '.' << '0' << absCents;
}
//Uses iostream and cstdlib:
void Money::input( ) {
char dollarSign;
cin >> dollarSign; //hopefully
if (dollarSign != '$'){
cout << "No dollar sign in Money input.\n";
exit(1);
}
double amountAsDouble;
cin >> amountAsDouble;
dollars = dollarsPart(amountAsDouble);
cents = centsPart(amountAsDouble);
8-7
}
Money "+" Definition: Operator Overloading
• Definition of "+" operator for Money class:

Copyright © 2017 Pearson Education, Ltd. All rights reserved. 8-8


Overloaded "=="
• Equality operator, ==
– Enables comparison of Money objects
– Declaration
bool operator ==(const Money& amount1, const Money& amount2);
• Returns bool type for true/false equality
– Again, it’s a non-member function (like "+" overload)

8-9
Constructors Returning Objects
• Constructor a "void" function?
– We "think" that way, but no
– A "special" function
• With special properties
• CAN return a value!

• Recall return statement in "+" overload for Money type:


– return Money(finalDollars, finalCents);
• Returns an "invocation" of Money class!
• So constructor actually "returns" an object!
• Called an "anonymous object"

8-10
Returning by const Value
• Consider "+" operator overload again:
const Money operator +(const Money& amount1, const Money& amount2);
– Returns a "constant object"?
– Why?
• Consider impact of returning "non-const“
Money operator +(const Money& amount1,const Money& amount2);

• Consider expression that calls: m1 + m2


– Where m1 & m2 are Money objects and object returned is Money object
– We can "do things" with objects!
• Like call member functions…
• (m1+m2).output();//Legal, right? Not a problem: doesn’t change anything
• (m1+m2).input();//Legal! PROBLEM! MODIFIES!
• Allows modification of "anonymous" object!
• Can’t allow that here!

• So we define the return object as const


8-11
Overloading Unary Operators
• C++ has unary operators: defined as taking one operand
– e.g., - (negation)
• x = -y; // Sets x equal to negative of y
– Other unary operators:
• ++, --

• Unary operators can also be overloaded


• Overloaded "-" function declaration
– Placed outside class definition:
const Money operator –(const Money& amount);
– Notice: only one argument since only 1 operand (unary)
• "-" operator is overloaded twice!
– For two operands/arguments (binary)
– For one operand/argument (unary)
– Definitions must exist for both
8-12
Overloaded "-" Definition and usage
• Overloaded "-" function definition:
const Money operator –(const Money& amount)
{
return Money(-amount.getDollars(), -amount.getCents());
}

• Applies "-" unary operator to built-in type


– Operation is "known" for built-in types
• Returns anonymous object again

money amount1(10), amount2(6), amount3;


amount3 = amount1 – amount2; // Calls binary "-" overload
amount3.output(); //Displays $4.00
amount3 = -amount1; //Calls unary "-" overload
amount3.output(); //Displays -$10.00

8-13
Overloading as Member Functions
• Previous example: operators were overloaded as standalone
functions, defined outside a class
• Can overload operator as "member operator“ considered "member
function" like others
• When operator is member function:
const Money operator +(const Money& amount);
– Only ONE parameter, not two!
– Calling object serves as 1st parameter
• Example:
Money cost(1, 50), tax(0, 15), total;
total = cost + tax;
– If "+" overloaded as member operator:
• Variable/object cost is calling object
• Object tax is single argument
– Think of as: total = cost.+(tax);
8-14
class Money {
public: //same as previous example but operator overload class member functions
const Money operator +(const Money& amount2) const;
const Money operator -(const Money& amount2) const;
bool operator ==(const Money& amount2) const;
const Money operator -() const;
private: //same as previous example
};
int main( ){//same as previous example }
const Money Money:: operator +( const Money& secondOperand) const {
int allCents1 = cents + dollars * 100;
int allCents2 = secondOperand.cents + secondOperand.dollars * 100;
int sumAllCents = allCents1 + allCents2;
int absAllCents = abs(sumAllCents); //Money can be negative.
int finalDollars = absAllCents / 100;
int finalCents = absAllCents % 100;
if (sumAllCents < 0){
finalDollars = -finalDollars;
finalCents = -finalCents;
}
return Money(finalDollars, finalCents);
}
const Money Money:: operator -( const Money& secondOperand) const { }
bool Money:: operator ==( const Money& secondOperand) const { }
const Money Money:: operator -( ) const{}
// <The rest of these definition is Self-Test Exercise .>
8-15
Constructors for Automatic Type Conversion
Money baseAmount(100, 60), fullAmount;
fullAmount = baseAmount + 25; The output would be $125.60
fullAmount.output( );

• We overloaded operator + to use it with two values of type Money.


– not with a value of type Money and an integer
– constant 25 can be considered to be of type int
– 25 should be converted to object of type Money
• auto type conversion:
– Works if there is a constructor that takes a single argument of type int
• System checks first to see if operator + has been overloaded for the
type combination of Money and integer.
– If not, it checks if there is a constructor that takes a single integer argument.
• If found, it uses it to convert the integer 25 to a value of type Money

• What about : fullAmount = 25+ baseAmount; //???8-16


Friend Functions
• Friends are nonmember functions
• Recall: operator overloads as nonmembers
• They access data through accessor and mutator functions

• Very inefficient (overhead of calls)

• Friends can directly access private class data Just as member


functions do
– No overhead, more efficient

– Avoids need to call accessor/mutator member functions

• Operator Overloads: Most common use of friends


• Use keyword friend in front of function declaration
– Specified IN class definition but they’re NOT member functions!
8-17
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
//Class for amounts of money in U.S. currency
class Money {
public:
Money( );
Money( double amount);
Money( int theDollars, int theCents);
Money( int theDollars);
double getAmount( ) const;
int getDollars( ) const;
int getCents( ) const;
void input( ); //Reads the dollar sign as well as the amount number.
void output( ) const;
friend const Money operator +(const Money& amount1, const Money& amount2);
friend const Money operator -(const Money& amount1, const Money& amount2);
friend bool operator ==( const Money& amount1, const Money& amount2);
friend const Money operator -( const Money& amount);
private:
int dollars; //A negative amount is represented as negative dollars and
int cents; //negative cents. Negative $4.50 is represented as -4 and -50.
int dollarsPart( double amount) const;
int centsPart( double amount) const;
int round( double number) const;
8-18
};
int main( ){
Money yourAmount, myAmount(10, 9);
cout << "Enter an amount of money: ";
yourAmount.input( );
cout << "Your amount is "; Enter an amount of money: $123.45
yourAmount.output( ); Your amount is $123.45
cout << endl; My amount is $10.09.
cout << "My amount is "; One of us is richer.
myAmount.output( ); $123.45 + $10.09 equals $133.54
cout << endl; $123.45 - $10.09 equals $113.36
if (yourAmount == myAmount)
cout << "We have the same amounts.\n";
else
cout << "One of us is richer.\n";
Money ourAmount = yourAmount + myAmount;
yourAmount.output( ); cout << " + "; myAmount.output( );
cout << " equals "; ourAmount.output(); cout << endl;
return 0;
}

8-19
const Money operator +(const Money& amount1, const Money& amount2) {
int allCents1 = amount1.cents + amount1.dollars*100;
int allCents2 = amount2.cents + amount2.dollars* 100;
int sumAllCents = allCents1 + allCents2;
int absAllCents = abs(sumAllCents); //Money can be negative.
int finalDollars = absAllCents / 100;
int finalCents = absAllCents % 100;
if (sumAllCents < 0){
finalDollars = -finalDollars;
finalCents = -finalCents;
}
return Money(finalDollars, finalCents);
}
const Money operator -( const Money& amount1, const Money& amount2)
//<The complete definition is Self-Test>

bool operator ==( const Money& amount1, const Money& amount2){


return ((amount1.dollars == amount2.dollars)
&& (amount1.cents == amount2.cents));
}
const Money operator -( const Money& amount){
return Money(-amount.dollars, -amount.cents);
} 8-20
References
• Reference defined as the name of a storage location
• Example of standalone reference:
int robert;
int& bob = robert;
• bob is reference to storage location for robert
• Changes made to bob will affect robert
• Useful in several cases: call-by- reference, returning a reference
• Returning a reference:
– operator overload can be written more naturally
– Think of as returning an "alias" to a variable
– function declaration: double& sampleFunc(double& var1);
– function definition: double& sampleFunc(double& var1){
// statements
return var1;
}

• double& and double are different


• Must match in function declaration and heading and "have" a reference
8-21
– Cannot be expression like "x+5“ because it has no place in memory to "refer to“
Overloading >> and <<
• Enables input and output of our objects
– Similar to other operator overloads
• Improves readability like all operator overloads do
– Enables: Money amount1(100), amout2;
cout << amount1;
cin >> amount2;
– Instead of need for: amount1.output(); amount2.input();
– Nicer if we can use << operator:
cout << "I have " << amount1 << endl;
instead of:
cout << "I have ";
amount1.output()
• file I/O objects and objects cin and cout are called streams
– iostream, ostream
8-22
cout << "Hello";
Overloading <<
– Operator is <<
– 1st operand is predefined object cout From library iostream
– 2nd operand is literal string "Hello“
cout << amount
– 2 operands are object cout from library iostream and object amount
• overloading operator << but what value does cout << amount
return?
– cascades: cout << "I have " << amount;
– is equivalent to the following : (cout << "I have ") << amount;
– First evaluates : (cout << "I have ")
• Return cout of type ostream
– second evaluates : cout << amount
• Return cout of type ostream
• operator << should return its first argument of type ostream
• overloaded operator << (to use with the class Money )
friend ostream& operator <<(ostream& outs, const Money& amount);
8-23
Overloading
<< and >>

8-24
Overloading
<< and >>

8-25
Overloading
<< and >>

void Money::output( ) const {


int absDollars = abs(dollars);
int absCents = abs(cents);
if (dollars < 0 || cents < 0)
cout << "$-";
else
cout << '$';
cout << absDollars;
if (absCents >= 10)
cout << '.' << absCents;
else
cout << '.' << '0' << absCents;
} 8-26
Overloading
<< and >>

void Money::input( ){
char dollarSign;
cin >> dollarSign; //hopefully
if (dollarSign != '$'){
cout << "No dollar sign in Money input.\n";
exit(1);
}
double amountAsDouble;
cin >> amountAsDouble;
dollars = dollarsPart(amountAsDouble);
cents = centsPart(amountAsDouble);
} 8-27
Assignment Operator, =

• Must be overloaded as member operator


• Automatically overloaded
– Default assignment operator:
• Member-wise copy
• Member variables from one object 
corresponding member variables from other
• Default OK for simple classes
– But with pointers  must write our own!

8-28

You might also like