By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on...

26
By By Joaquin Vila Joaquin Vila Prepared by Prepared by Sally Scott Sally Scott ACS 168 ACS 168 Problem Solving Using the Problem Solving Using the Computer Computer Week 13 More on Classes Chapter 8

Transcript of By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on...

Page 1: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

ByBy

Joaquin VilaJoaquin Vila

Prepared byPrepared by

Sally ScottSally Scott

ACS 168ACS 168Problem Solving Using the ComputerProblem Solving Using the Computer

ACS 168ACS 168Problem Solving Using the ComputerProblem Solving Using the Computer

Week 13

More on Classes

Chapter 8

Week 13

More on Classes

Chapter 8

Page 2: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Tools for Defining ADTs

Defining ADT Operations Friend Functions Implementation of digit_to_int The const Parameter Modifier Constructors for Automatic Type Conversion Overloading Unary Operations Overloading >> and <<

Page 3: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Friend Functions

An ordinary function that is given special access to the private members of a class

NOT a member function of the class Prototype is listed in the class definition Keyword friend goes in front of the

prototype

Page 4: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Program to demonstrate the function equal.#include <iostream>

using namespace std;

class DayOfYear

{ public:

DayOfYear(int the_month, int the_day);

//Initializes the date according to the arguments.

DayOfYear( ); //Initializes the date to January first.

void input( );

void output( );

int get_month( ); //Returns the month, 1 for January, 2 for February, etc.

int get_day( ); //Returns the day of the month.

private:

int month;

int day;

};

Page 5: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

bool equal(DayOfYear date1, DayOfYear date2); //Precondition: date1 and date2 have values.//Returns true if date1 and date2 represent the same date,//otherwise returns false.int main( ){ DayOfYear today, bach_birthday(3, 21); cout << "Enter today's date:\n"; today.input( ); cout << "Today's date is "; today.output( ); cout << "J. S. Bach's birthday is "; bach_birthday.output( ); if ( equal(today, bach_birthday)) cout << "Happy Birthday Johann Sebastian!\n"; else cout << "Happy Unbirthday Johann Sebastian!\n"; return 0;}

Function call: sends today and bach_birthday

Function call: sends today and bach_birthday

This function is defined outside the class.

It is NOT a member function, but rather a typical function.

This function is defined outside the class.

It is NOT a member function, but rather a typical function.

Page 6: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

//Function definition for equal bool equal(DayOfYear date1, DayOfYear date2){

return ( date1.get_month( ) == date2.get_month( ) && date1.get_day( ) == date2.get_day( ) );}//Function definitions for DayOfYear classDayOfYear::DayOfYear(int the_month, int the_day){

month = the_month; day = the_day;}DayOfYear::DayOfYear( ){

month = 1; day = 1;}int DayOfYear::get_month( ){ return month;}

Notice there is no scope resolution operator since it is not a member function of the class.

Notice there is no scope resolution operator since it is not a member function of the class.

Page 7: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

int DayOfYear::get_day( ){

return day;}

//Uses iostream:void DayOfYear::input( ){ cout << "Enter the month as a number: "; cin >> month; cout << "Enter the day of the month: "; cin >> day;}

//Uses iostream:void DayOfYear::output( ){

cout << "month = " << month << ", day = " << day << endl;

}

Page 8: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

The equal function must use accessor functions.

bool equal(DayOfYear date1, DayOfYear date2){

return ( date1.get_month( ) == date2.get_month( ) && date1.get_day( ) == date2.get_day( ) );

} Here the function is implemented as a “stand-alone”

function. The problem is, a stand-alone function, defined outside a

class, must use accessor functions. It is possible to allow ordinary functions to have direct

access to data members (even though those members are private).

An ordinary function declared as a friend of the class gains the required access.

Page 9: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Friend Functions An ordinary function declared as a friend of the

class gains direct access to private data members without going through member functions.

The class grants friend status by declaring the function with the friend keyword.

When a friend function is defined, you do not use the class name and scope resolution operator as you do with members.

Page 10: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Declaring a function as a friendclass DayOfYear Here equal is granted friend status {public: friend bool equal(DayOfYear date1, DayOfYear date2); //Precondition: date1 and date2 have values. //Returns true if date1 and date2 represent the same date; otherwise returns false. DayOfYear(int the_month, int the_day); DayOfYear( ); void input( ); void output( ); int get_month( ); int get_day( );private: int month; int day;};

Page 11: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Friend vs Regular Function

If the function is listed as a friend in the class definition, the function definition looks like this…

bool equal(DayOfYear date1, DayOfYear date2){

return ( date1.month == date2.month && date1.day == date2.day )}

If the function is NOT listed as a friend in the class definition, the function definition looks like this…

bool equal(DayOfYear date1, DayOfYear date2){

return ( date1.get_month( ) == date2.get_month( ) && date1.get_day( ) == date2.get_day( ) );

}

Page 12: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Review of Friend Functions A friend function of a class is an ordinary (non-member)

function that has access granted to private members of a that class.

To make a function a friend of a class list that function prototype in the class with the keyword friend. The prototype may be placed in either the public or the private section of

the class.

A friend function is NOT a member function. A friend function is defined and called the same way as any ordinary

function.

You do not use the dot operator to call a friend function, and you do not use a class resolution operator in the definition of a friend function.

Page 13: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Consider this code fragment from a mainline function:

DayOfYear today; //declaration of an instance of the class

cout << “enter today’s date: \n”;today.input();cout << “There are << (12 - today.get_month()) << “ months left in the year. \n”;

You cannot replace today.get_month() with today.month because month is a private data member.

The function get.month() is a public member function used to access the value stored in the private data member month.

Main does not have direct access because it is not listed as a friend.

Page 14: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Use both Member and Nonmember functions.

Members and friends of a class do similar services for a class. To clarify whether a given task should be done by a friend or member,

consider: Use a member function if the task being performed by the function

involves only one object. Use a nonmember function if the task being performed involves more

than one object.

Example: The function equal involves two objects, so we make it a friend.bool equal(DayOfYear date1, DayOfYear date2){ return ( date1.month == date2.month &&

date1.day == date2.day ); }

Whether member or non-member is not always as simple as this rule suggests.

Clarity and readability is the cardinal rule for this issue.

Page 15: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

The const Parameter Modifier Call-by-value vs. call-by-reference

Call-by-value creates second copy of values Call-by-value ensures function cannot change parameters Call-by-reference more efficient for large objects such as

classes

For classes use call-by-reference with keyword const The const modifier allows you to pass a parameter by

reference (saving overhead) but guarantees not to change the current value.

The compiler will emit error messages when you compile code that does change the parameter

Page 16: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

The const Parameter ModifierExample:

Money add(const Money& amount1, const Money& amount2);

Here any code written in the implementation of the add function that might change amount1 or amount2 will be marked as an error.

Page 17: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Prototype and Header MUST agree

If you use the const parameter modifier in your prototype in your class, you MUST use the const modifier in exactly the same way in your definition, or you will get errors when you compile your code.

Example:

class SomeClass{public: void aFunc( const int & aVar, double & bVar); friend int compare(const Date & date1, const Date & date2);};

void SomeClass::aFunc(const int & aVar, double & bVar){// whatever aFunc does}

const in prototype

must have const in function definition

const in prototype

must have const in function definition

Page 18: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Use const with member functions Use const when member function does not change

value of calling objectClass SomeClass{ void output(ostream & outifle) const;};void SomeClass::output(ostream & outfile) const{ // does output}

int main(){

SomeClass ObjA; ObjA.output(outfile); …..}

in application, output function cannot change ObjA

in application, output function cannot change ObjA

Page 19: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

What does const do in each of these cases?

const int x = 17;class AClass{public: AClass( ); AClass(int); int aFunc( ) const; int bFunc(const AClass& obj1);private: int i; };

Page 20: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Overloading Operators

C++ provides many operators for manipulating primitive data type such as +, -, *, /, >, <, >>, <<

Since C++ does not know how to manipulate our classes, it provides a way to program ADTs with functions that behave “like” built-in types (primitive types).

Overloading operators allows ADTs to use operators such as +, -, stream i/o using << and >> with behavior that the programmer specifies.

Page 21: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Consider adding 2 money objects

prototypefriend Money operator +(const Money& val1, const Money& val2);

Function definitionMoney operator +(const Money& amt1, const Money& amt2){ Money temp; temp.all_cents = amt1.all_cents + amt2.all_cents; return temp;}

in the application you can do this:Money cost(1, 50), tax (0, 15), total;total = cost + tax;

Page 22: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Consider testing for equality by overloading ==

prototypefriend bool operator ==(const Money& amt1, const Money& amt2);

Function definitionbool operator ==(const Money& amt1, const Money& amt2){ return (amt1.all_cents == amt2.all_cents);}

As used in application:Money cost(1, 50), tax(0, 15);….if (cost == tax){ ……

Page 23: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Rules for overloading operator functions At least one argument must be of a class type. Must be a friend to or a member of a class. Must be an existing operator. Must keep the operator’s number of arguments. Must keep the operator’s precedence. Some operators cannot be overloaded (. ::). Some must be overloaded in a different way (=) not covered

in 168. Don’t overuse operator overloading. It can lead to unreadable

code. Make sure that the overloaded operator really makes sense

and that you won’t be confusing people trying to read your code.

Page 24: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Overloading << and >>

One of the very useful things to overload for most classes.

Must return a reference to the output or input stream. Why?

cout << "I have " << amount << " in my purse.\n "; ((cout << "I have ") << amount) << " in my purse.\n "; operator<< (cout, “I have “) returns cout giving… (cout << amount) << " in my purse.\n "; operator<< (cout << amount) again returns cout cout<< " in my purse.\n ";

Page 25: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

 // returns istream&:istream& operator >> (istream& infile, Money& amount){//all the necessary code to fetch the

amount//from the istream and do some format

checking //see input functionreturn infile;

} ostream& operator << (ostream& outfile, Money& amount){//all the necessary code to fetch the

amount//from the istream and do some format

checking // see output functionreturn outfile;

}

Page 26: By Joaquin Vila Prepared by Sally Scott ACS 168 Problem Solving Using the Computer Week 13 More on Classes Chapter 8 Week 13 More on Classes Chapter 8.

Using overloaded << and >> in application

Money amount; . . .

Stream declarations, file opening, etc

infile >> amount;outfile << amount;