Tải bản đầy đủ (.pdf) (18 trang)

Lecture 13 operator overloading v1 2 tủ tài liệu training

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (985.55 KB, 18 trang )

Lecture 13 - Operator
Overloading

Lumina Inova


Lecture 13 – Operator Overloading
 Giving the normal C++ operators such as +, -, * , <=, and += etc. , additional
meanings when they are applied to user-defined types (classes).
 You cannot create new operators like *& and try to overload them; only existing
operators can be overloaded.
 The precedence of an operator cannot be changed by overloading.
 The associativity of an operator cannot be changed.
 The polarity of an operator cannot be changed.
 The meaning of how an operator works on built-in types cannot be changed:
 Operator overloading works only on objects of user defined types or with a
mixture of user-defined and built-in types.
 At least one argument of an operator function must be a class object or a
reference to a class object.
 Operators that cannot be overloaded “::” , “ ?: ” , “ .” , “ .*”.
 Operators that can be used without overloading “= ”

“ , ” “&”.

 Operator functions can be member functions or global friend functions.

Creating a Member Operator Function
ret-type class-name::operator # (arg-list)
{
//operations
}



Page | 1

Copyright 2015 – Lumina Inova


Creating a Global Operator Function
ret-type operator # (arg-list)
{
//operations
}

Overloading Unary Operators
class Counter{
private:
int count;
public:
Counter():count(0)
{
}
int getcount()
{return count;}
void operator ++()
{
++count;
}
};
// END OF CLASS
void main()
{

Counter c1, c2;
cout<<\nc1=“<cout<<“\nc2=“<++c1; //prefix
++c2; //prefix
++c2; //translated to
compiler
cout<<\nc1=“<cout<<“\nc2=“<}

Page | 2

// c2.operator++() by

Copyright 2015 – Lumina Inova


Operator Return Values
In the previous example, you cannot write
c1 =++ c2; //Error; Why?
Counter operator ++()
{
++count;
Counter temp;
temp.count=count;
return temp;
}

Postfix Notation

Counter operator ++(int)
{
count ++;
return (*this);
}



The only difference is in the int in the parenthesis.



This isn’t really an argument, and it doesn’t mean an integer.



It is simply a signal to the compiler to create a postfix version of the operator.

Overloading Binary Operators
class complex {
private:
int real, imag;
public:
complex(int re=0, int im=0): real(re),
{
}
void setdata()
{
cin>>real;
cin>>imag;

}
void showdata() const
{
cout<}
complex operator + (complex);
};

imag(im)

complex complex::operator + (complex c)
{ //note: we aim not to change the operands
int re2=real + c.real;

Page | 3

Copyright 2015 – Lumina Inova


int im2=imag+c.imag;
return complex(re2, im2);
}
void main()
{
complex c1, c2(1,2), c3, c4;
c1.setdata();
c3=c1+c2; //same as c1.operator + (c2)
c4 = c1+c2+ c3; //note cascading
c4. showdata();
}


In :
c3=c1+c2;


The argument on the LEFT side of the operator (c1 in this case) is the object of
which the operator is a member.



The argument on the RIGHT side of the operator (c2 in this case) must be
furnished as an argument to the operator.



The operator returns a value which can be assigned or used in other ways; in this
case it is assigned to c3.



An overloaded operator implemented as a member function always requires one
less argument than its no. of operands, since one operand is the object of which
the operator is a member. That is why unary operators require no arguments.

Page | 4

Copyright 2015 – Lumina Inova


Constant Data Members



Must be initialized with initializer list syntax.



All constant data members must be initialized.

Code Example
class Distance
//English Distance class
{
private:
int feet; float inches;
public:
//constructor (no args)
Distance() : feet(0), inches(0.0)
{ }
//constructor (two args)
Distance(int ft, float in) : feet(ft), inches(in)
{ }
void getdist()
//get length from user
{
cout << “\nEnter feet: ”;
cin >> feet;
cout << “Enter inches: ”;
cin >> inches;
}
void showdist() const

//display distance
{ cout << feet << “\’–” << inches << ‘\”’;
}
Distance add_dist(const Distance&) const; //add
};
//add this distance to d2, return the sum
Distance Distance::add_dist( Distance& d2) const
{
Distance temp;
//temporary variable
// feet = 0;
//ERROR: can’t modify this
d2 temp.inches = inches + d2.inches;
//add the inches
if(temp.inches >= 12.0)
//if total exceeds 12.0,
{
//then decrease inches
temp.inches –= 12.0;
//by 12.0 and
temp.feet = 1;
//increase feet
}
//by 1
temp.feet += feet + d2.feet;
//add the feet
return temp;
}

Page | 5


Copyright 2015 – Lumina Inova


Constant Objects
 When an object is declared as const, you can’t modify it.
 It follows that you can use only const member functions with it, because they’re
the only ones that guarantee not to modify it.

Composition
 Definition: A data member of a class is an object of some other class.
 Example: an AlarmClock object needs to know when it is supposed to sound its
alarm, so why not include a Time object as a member of the AlarmClock class?
 Referred to as has-a relationship.
 Reusability.

Order of Constructor and Destructor for Composition
 Member objects are constructed in the order in which they are declared in the
class definition (not in the order they are listed in the constructor’s member
initializer list) and before their enclosing class objects are constructed.
 Member objects are constructed from inside out and destroyed in the reverse
order.
 Compilation error occurs if a member object is not initialized with a member
initializer and the member object’s class doesn’t not provide a default
constructor.
 Initialize member objects explicitly through member initializers. This eliminates
the overhead of doubly initializing.

Page | 6


Copyright 2015 – Lumina Inova


Operators functions as Member Functions vs Global
Functions
 When right operand is an object of a user defined class.
 Commutative operators.
operators ->, (), [] can only be overloaded through member functions.

Example of overloading () and << operators
class loc
{
friend ostream& operator <<(ostream & , loc);
private:
int longitude, latitude;
public:
loc(int lon=0, int lat= 0): longitude(lon), latitude(lat)
{}
loc operator ()(int i , int j)
{
longitude =i;
latitude=j;
return *this;
}
};

ostream& operator <<(ostream & out, loc l)
{
out<< " longitude is : "<out<< " latitude is : "<

return out;
}
void main()
{
loc obj1(2,3);
loc obj2(8,9);
cout<cout<obj1(11,99);
cout<}

Page | 7

Copyright 2015 – Lumina Inova


Quiz
1. Operator overloading is:
a. making C++ operators work with objects.
b. giving C++ operators more than they can handle.
c. giving new meanings to existing C++ operators.
d. making new C++ operators.
2. Assuming that class X does not use any overloaded operators, write a statement that
subtracts an object of class X, x1, from another such object, x2, and places the result in
x3.
3. Assuming that class X includes a routine to overload the - operator, write a statement
that would perform the same task as that specified in Question 2.
4. True or false: The >= operator can be overloaded.
5. Write a complete definition for an overloaded operator for the Counter class of the

COUNTPP1 example that, instead of incrementing the count, decrements it.
6. How many arguments are required in the definition of an overloaded unary operator?
7. Assume a class C with objects obj1, obj2, and obj3. For the statement obj3 =
obj1 - obj2 to work correctly, the overloaded - operator must:
a. take two arguments.
b. return a value.
c. create a named temporary object.
d. use the object of which it is a member as an operand.
8. Write a complete definition for an overloaded ++ operator for the Distance class from
the ENGLPLUS example. It should add 1 to the feet member data, and make possible
statements like
dist1++;
9. Repeat Question 8, but allow statements like the following:
dist2 = dist1++;
10. When used in prefix form, what does the overloaded ++ operator do differently from
what it does in postfix form?
11. Here are two declarators that describe ways to add two string objects:
void add(String s1, String s2)
String operator + (String s)
Match the following from the first declarator with the appropriate selection from the
second:
function name (add) matches _________.
return value (type void) matches _________.
Page | 8

Copyright 2015 – Lumina Inova


first argument (s1) matches _________.
second argument (s2) matches _________.

object of which function is a member matches _________.
a. argument (s)
b. object of which operator is a member
c. operator (+)
d. return value (type String)
e. no match for this item
Operator Overloading
12. True or false: An overloaded operator always requires one less argument than its number
of operands.

Page | 9

Copyright 2015 – Lumina Inova


Exercise
1). To the Distance class in the program below, add an overloaded - operator that
subtracts two distances. It should allow statements like dist3=dist1-dist2; Assume that
the operator will never be used to subtract a larger number from a smaller one (that is,
negative distances are not allowed).
#include <iostream>
using namespace std;
////////////////////////////////////////////////////////////////
class Distance //English Distance class
{
private:
int feet;
float inches;
public: //constructor (no args)
Distance() : feet(0), inches(0.0)

{ } //constructor (two args)
Distance(int ft, float in) : feet(ft), inches(in)
{ }
void getdist() //get length from user
{
cout << “\nEnter feet: “; cin >> feet;
cout << “Enter inches: “; cin >> inches;
}
void showdist() const //display distance
{ cout << feet << “\’-” << inches << ‘\”’; }
Distance operator + ( Distance ) const; //add 2 distances
};
//-------------------------------------------------------------//add this distance to d2
Distance Distance::operator + (Distance d2) const //return sum
{
int f = feet + d2.feet; //add the feet
float i = inches + d2.inches; //add the inches
if(i >= 12.0) //if total exceeds 12.0,
{ //then decrease inches
i -= 12.0; //by 12.0 and
f++; //increase feet by 1
} //return a temporary Distance
return Distance(f,i); //initialized to sum
}

Page | 10

Copyright 2015 – Lumina Inova



2. Write a program that substitutes an overloaded += operator for the overloaded +
operator in the Program below. This operator should allow statements like s1 += s2;
where s2 is added (concatenated) to s1 and the result is left in s1. The operator should
also permit the results of the operation to be used in other calculations, as in s3 = s1 +=
s2;
#include <iostream>
using namespace std;
#include <string.h> //for strcpy(), strcat()
#include <stdlib.h> //for exit()
////////////////////////////////////////////////////////////////
class String //user-defined string type
{
private:
enum { SZ=80 }; //size of String objects
char str[SZ]; //holds a string
public:
String() //constructor, no args
{ strcpy(str, “”); }
String( char s[] ) //constructor, one arg
{ strcpy(str, s); }
{
String temp; //make a temporary String
if( strlen(str) + strlen(ss.str) < SZ )
{
strcpy(temp.str, str); //copy this string to temp
strcat(temp.str, ss.str); //add the argument string
}
else
{ cout << “\nString overflow”; exit(1); }
return temp; //return temp String

}
};

3). Create a class called time that has separate int member data for hours, minutes, and
seconds. One constructor should initialize this data to 0, and another should initialize
into fixed values. Another member function should display it, in 11:59:59 format. The
final member function should add two objects of type time passed as arguments.
A main() program should create two initialized time objects (should they be const?) and
one that isn’t initialized. Then it should add the two initialized values together, leaving
the result in the third time variable. Finally it should display the value of this third
variable.
Make appropriate member functions const.
Modify the time class in the question above so that instead of a function
add_time() it uses the overloaded + operator to add two times. Write a program to
test this class.

Page | 11

Copyright 2015 – Lumina Inova


Answers
1. a, c
2. x3.subtract(x2, x1);
3. x3 = x2 - x1;
4. true
5. void operator -- () { count--; }
6. none
7. b, d
8.

void Distance::operator ++ ()
{
++feet;
}

9.
Distance Distance::operator ++ ()
Distance Distance::operator ++ ()
{
int f = ++feet;
float i = inches;
return Distance(f, i);
}

10. It increments the variable prior to use, the same as a non-overloaded ++operator.
11. c, e, b, a, d
12. true

Page | 12

Copyright 2015 – Lumina Inova


Exercises
1)
// overloaded ‘-’ operator subtracts two Distances
#include <iostream>
using namespace std;
////////////////////////////////////////////////////////////////
class Distance //English Distance class

{
private:
int feet;
float inches;
public: //constructor (no args)
Distance() : feet(0), inches(0.0)
{ } //constructor (two args)
Distance(int ft, float in) : feet(ft), inches(in)
{ }
void getdist() //get length from user
{
cout << “\nEnter feet: “; cin >> feet;
cout << “Enter inches: “; cin >> inches;
}
void showdist() //display distance
{ cout << feet << “\’-” << inches << ‘\”’; }
Distance operator + ( Distance ); //add two distances
Distance operator - ( Distance ); //subtract two distances
};
//-------------------------------------------------------------//add d2 to this distance
Distance Distance::operator + (Distance d2) //return the sum
{
int f = feet + d2.feet; //add the feet
float i = inches + d2.inches; //add the inches
if(i >= 12.0) //if total exceeds 12.0,
{ //then decrease inches
i -= 12.0; //by 12.0 and
f++; //increase feet by 1
} //return a temporary Distance
return Distance(f,i); //initialized to sum

}
//-------------------------------------------------------------//subtract d2 from this dist
Distance Distance::operator - (Distance d2) //return the diff
{
int f = feet - d2.feet; //subtract the feet
float i = inches - d2.inches; //subtract the inches
if(i < 0) //if inches less than 0,
{ //then increase inches
i += 12.0; //by 12.0 and
f--; //decrease feet by 1
} //return a temporary Distance
return Distance(f,i); //initialized to difference
}
////////////////////////////////////////////////////////////////
int main()
{
Distance dist1, dist3; //define distances

Page | 13

Copyright 2015 – Lumina Inova


dist1.getdist(); //get dist1 from user
Distance dist2(3, 6.25); //define, initialize dist2
dist3 = dist1 - dist2; //subtract
//display all lengths
cout << “\ndist1 = “; dist1.showdist();
cout << “\ndist2 = “; dist2.showdist();
cout << “\ndist3 = “; dist3.showdist();

cout << endl;
return 0;
}

Page | 14

Copyright 2015 – Lumina Inova


2)
// overloaded ‘+=’ operator concatenates strings
#include <iostream>
#include <cstring> //for strcpy(), strlen()
using namespace std;
#include //for exit()
////////////////////////////////////////////////////////////////
class String //user-defined string type
{
private:
enum { SZ = 80 }; //size of String objects
char str[SZ]; //holds a C-string
public:
String() //no-arg constructor
{ strcpy(str, “”); }
String( char s[] ) //1-arg constructor
{ strcpy(str, s); }
void display() //display the String
{ cout << str; }
String operator += (String ss) //add a String to this one
{ //result stays in this one

if( strlen(str) + strlen(ss.str) >= SZ )
{
cout << “\nString overflow”;
exit(1);
}
strcat(str, ss.str); //add the argument string
return String(str); //return temp String
}
};
////////////////////////////////////////////////////////////////
int main()
{
String s1 = “Merry Christmas! “; //uses 1-arg ctor
String s2 = “Happy new year!”; //uses 1-arg ctor
String s3; //uses no-arg ctor
s3 = s1 += s2; //add s2 to s1, assign to s3
cout << “\ns1=”; s1.display(); //display s1
cout << “\ns2=”; s2.display(); //display s2
cout << “\ns3=”; s3.display(); //display s3
cout << endl;
return 0;
}

Page | 15

Copyright 2015 – Lumina Inova


3)
#include <iostream>

using namespace std;
////////////////////////////////////////////////////////////////
class time
{
private:
int hrs, mins, secs;
public:
time() : hrs(0), mins(0), secs(0) //no-arg constructor
{ } //3-arg constructor
time(int h, int m, int s) : hrs(h), mins(m), secs(s)
{ }
void display() //format 11:59:59
{ cout << hrs << “:” << mins << “:” << secs; }
time operator + (time t2) //add two times
{
int s = secs + t2.secs; //add seconds
int m = mins + t2.mins; //add minutes
int h = hrs + t2.hrs; //add hours
if( s > 59 ) //if secs overflow,
{ s -= 60; m++; } // carry a minute
if( m > 59 ) //if mins overflow,
{ m -= 60; h++; } // carry an hour
return time(h, m, s); //return temp value
}
};
////////////////////////////////////////////////////////////////
int main()
{
time time1(5, 59, 59); //create and initialze
time time2(4, 30, 30); // two times

time time3; //create another time
time3 = time1 + time2; //add two times
cout << “\ntime3 = “; time3.display(); //display result
cout << endl;
return 0;
}

~END~

Page | 16

Copyright 2015 – Lumina Inova


Feedback
If this course has helped you, please leave a positive review. If not, please contact me in the
discussion area where I will help you with any course related issues or problems. I am there to
help you and this is an ongoing course, so any suggestions I will use to improve this course.
This is to create a better student experience as possible for all students.

Page | 17

Copyright 2015 – Lumina Inova



×