Transcript PPT

CSCI-383
Object-Oriented Programming & Design
Lecture 11
Operator Overloading
 Most C++ operators can be overloaded
 Overloaded operators are implemented using the
C++ keyword operator
 There are some characteristics of the operators that
cannot be changed when overloading them





New operator names cannot be introduced
Builtin operators cannot be overriden
Operator precedences cannot be changed
Operator associativity cannot be changed
The number of operator parameters cannot be
changed
Operator Overloading
 Handout #2
 Notice that the Timer class contains an overloaded
addition operator, which is a binary operator
 In the addition operator of Timer, the receiver of the
message is the left (first) argument of “+”, and the
argument is the second argument of “+”
Global vs. Method Operators
 Instead, one could defined the previous overloaded
operator as a global function rather than as a
method
Timer operator+(const Timer& t1, const
Timer& t2) { … }
 Notice the difference between the global and the
method definition: the first argument is missing in
the method version…or is it?
 this serves as the first (left) argument of the operator
 this is a builtin, self-referential identifier; it contains
the address of the receiving object
 In such a case, an operator call such as time1 +
time2 is a message sent to the Timer instance time1
Global vs. Method Operators
 Overloaded operators can be called in either
operator form or functional form
 time0 = time1 + time2; // operator form
 time0 = time1.operator+(time2) // functional
form
 The same rules hold for unary operators. For
example, consider the “not” operators (i.e., “!”)
 int operator!(const Timer& t); // as global
function
 int Timer::operator!(void) const; // as
method
 Equivalent calls to overloaded operator !
 if (!time1) …
 if (time1.operator!()) …
The Subscripting Operator
 The second example of handout #2 illustrates an
implementation of an overloaded subscripting
operator (i.e., “[]”)
 Here is an example that uses it
IntArray c1(5);
for(int i=0; i<5; i++)
{
c1[i] = i;
cout << c1[i] << endl;
}
The Function Call Operator
 The second example of handout #2 also illustrates
an implementation of an overloaded function call
operator (i.e., “()”)
 Here is an example that uses it
IntArray c1(5);
// …
for(int i=0; i<5; i++)
cout << c1() << endl;
 The function call operator can be defined with zero
or more parameters in its parameter list
Conversion Operators
 A conversion operator converts an instance of the
class of which it is a member to an instance of a
builtin class (type)
Timer::operator int(void)
{
return hours*3600+minutes*60+int(seconds);
}
 Conversion operators have no return type specified
explicitly since the name of the operator specifies the
return type. They also always have a void parameter
list
Overloaded Operator Q&A
 Q: What if one wants to use objects as conditions?
For example:
if (time1) …
if (!time1) …
 A: Define these operators as the methods:
operator int(void);
int operator!(void);
Overloaded Operator Q&A
 Q: What if one wants to overload both prefix and
infix ++?
 A: In the C++ standard, the two are distinguished
as illustrated in the following examples
Prefix Overloaded Method
Timer Timer::operator++(void)
{
if (++seconds >= 60.0) {
minutes++;
seconds -= 60.0;
}
if (minutes >= 60) {
hours++;
minutes -= 60;
}
return *this;
}
Postfix Overloaded Method
Timer Timer::operator++(int i)
{
Timer temp = *this;
if (++seconds >= 60.0) {
minutes++;
seconds -= 60.0;
}
if (minutes >= 60) {
hours++;
minutes -= 60;
}
return temp;
}
WARNING! Since no actual value is sent to the int parameter, do not use the
parameter in the method’s code!