120 likes | 143 Views
Learn about operator overloading in C++, including characteristics, global vs. method operators, subscripting and function call operators, conversion operators, and helpful Q&A.
E N D
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!