Operator Overloading
CS-2303 System Programming Concepts
(Slides include materials from The C Programming Language, 2nd edition, by Kernighan and Ritchie, from C: How to Program, 5th and 6th editions, by Deitel and Deitel, and from The C++ Programming Language, 3rd edition, by Bjarne Stroustrup)
CS-2303, C-Term 2010
Operator Overloading
Why Operator Overloading?
Readable code Extension of language to include userdefined types
I.e., classes
Make operators sensitive to context Generalization of function overloading
CS-2303, C-Term 2010 Operator Overloading 2
Simple Example
class complex { double real, imag; public: complex(double r, double i) : real(r), imag(i) {} }
Would like to be able to write:
complex a = complex(1, 3.0); complex b = complex(1.2, 2); complex c = b; I.e., would like to write ordinary arithmetic expressions a = b + c; on this user-defined class. b = b+c*a; c = a*b + complex(1,2);
CS-2303, C-Term 2010 Operator Overloading 3
With Operator Overloading, We Can
class complex { double real, imag; public: complex(double r, double i) : real(r), imag(i) {} complex operator+(complex a, complex b); complex operator*(complex a, complex b); complex& operator=(complex a, complex b); ... }
CS-2303, C-Term 2010 Operator Overloading 4
General Format
returnType operator*(parameters);
any type keyword operator symbol
Return type may be whatever the operator returns
Including a reference to the object of the operand
Operator symbol may be any overloadable operator from the list.
CS-2303, C-Term 2010
Operator Overloading
C++ Philosophy
All operators have context
Even the simple built-in operators of basic types E.g., '+', '-', '*', '/' for numerical types Compiler generators different code depending upon type of operands
Operator overloading is a generalization of this feature to non-built-in types
E.g., '<<', '>>' for bit-shift operations and also for stream operations
CS-2303, C-Term 2010 Operator Overloading 6
C++ Philosophy (continued)
Operators retain their precedence and associativity, even when overloaded Operators retain their number of operands Cannot redefine operators on built-in types
Not possible to define new operators
Only (a subset of) the built-in C++ operators can be overloaded
CS-2303, C-Term 2010 Operator Overloading 7
Operators that Can and Cannot be Overloaded
Operators that can be overloaded
+ ~ /= <<= -new[] ! %= == ->* delete[] * = ^= != , / < &= <= -> % > |= >= [] ^ += << && () & -= >> || new | *= >>= ++ delete
Deitel & Deitel, Figure 22.1
Operators that cannot be overloaded
. .* :: ?:
Deitel & Deitel, Figure 22.2
CS-2303, C-Term 2010
Operator Overloading
Outline
Fundamentals of Operator Overloading Restrictions on Operator Overloading Operator Functions as Class Members vs. Global Functions Overloading Stream Insertion and Stream Extraction Operators
CS-2303, C-Term 2010
Operator Overloading
Operator Overload Function
Either
a non-static member function definition or a global function definition
Usually a friend of the class
Function name is keyword operator followed by the symbol for the operation being overloaded
E.g. operator+, operator=
CS-2303, C-Term 2010 Operator Overloading 10
Operator Overload Function (continued)
Operator overload function is a function just like any other Can be called like any other e.g.,
a.operator+(b)
C++ provides the following short-hand
a+b
CS-2303, C-Term 2010 Operator Overloading 11
Operator Overload Function (continued)
If operator overload function is declared global then
operator+(a, b)
also reduces to the following short-hand
a+b
CS-2303, C-Term 2010
Operator Overloading
12
Operator Overloading (continued)
To use any operators on a class object, The operator must be overloaded for that class. Three Exceptions: {overloading not required} Assignment operator (=) Memberwise assignment between objects Dangerous for classes with pointer members!! Address operator (&) Returns address of the object in memory. Comma operator (,)
Evaluates expression to its left then the expression to its right. Returns the value of the expression to its right.
CS-2303, C-Term 2010 Operator Overloading 13
Questions?
CS-2303, C-Term 2010
Operator Overloading
14
Operator Functions as Class Members
Leftmost operand must be of same class as operator function. Use this keyword to implicitly get left operand argument. Operators (), [], -> or any assignment operator must be overloaded as a class member function. Called when
Left operand of binary operator is of this class. Single operand of unary operator is of this class.
CS-2303, C-Term 2010 Operator Overloading 15
Operator Functions as Global Members
Need parameters for both operands. Can have object of different class than operator. Can be made a friend to access private or protected data.
CS-2303, C-Term 2010
Operator Overloading
16
Stream Insertion and Extraction Operators as Global Functions Overload << operator used where
Left operand of type ostream &
Such as cout object in cout << classObject
Overload >> has left operand of istream
Left operand of type istream &
&
Such as cin object in cout >> classObject
Reason:
These operators are associated with class of right operand
CS-2303, C-Term 2010 Operator Overloading 17
Commutative operators
May need + to be commutative
So both a + b and b + a work as expected.
Suppose we have two different classes
Overloaded operator can only be member function when its class is on left.
HugeIntClass + long int
Can be member function
For the other way, you need a global overloaded function.
long int + HugeIntClass
CS-2303, C-Term 2010 Operator Overloading 18
Example Deitel & Deitel 23.5
<<
and >> operators
Already overloaded to process each built-in type (pointers and strings). Can also process a user-defined class.
Overload using global, friend functions
Example program
Class PhoneNumber
Holds a telephone number
Prints out formatted number automatically.
(123) 456-7890
CS-2303, C-Term 2010 Operator Overloading 19
Example 23.5 (continued)
1 2 3 4 5 6 7 8 9 10 #include <string> 11 using std::string; 12 13 class PhoneNumber 14 { 15 16 18 19 20 22 23 #endif friend ostream &operator<<( ostream &, const PhoneNumber & ); friend istream &operator>>( istream &, PhoneNumber & ); string areaCode; // 3-digit area code string exchange; // 3-digit exchange string line; // 4-digit line #include <iostream> using std::ostream; using std::istream; // Fig. 22.3: PhoneNumber.h // PhoneNumber class definition #ifndef PHONENUMBER_H #define PHONENUMBER_H
Note also: returns a reference!
17 private:
21 }; // end class PhoneNumber
Notice function prototypes for overloaded operators >> and << (must be global, friend functions)
CS-2303, C-Term 2010
Operator Overloading
20
Example 23.5 (continued)
1 2 3 4 5 6 7 8 9 // overloaded stream insertion operator; cannot be 10 // a member function if we would like to invoke it with 11 // cout << somePhoneNumber; 12 ostream &operator<<( ostream &output, const PhoneNumber &number ) 13 { 14 15 16 output << "(" << number.areaCode << ") " << number.exchange << "-" << number.line; return output; // enables cout << a << b << c; #include "PhoneNumber.h" // Fig. 22.4: PhoneNumber.cpp // Overloaded stream insertion and stream extraction operators // for class PhoneNumber. #include <iomanip> using std::setw;
Allows cout << phone; to be interpreted as: operator<<(cout, phone);
17 } // end function operator<<
Display formatted phone number
CS-2303, C-Term 2010
Operator Overloading
21
Example 23.5 (continued)
18 19 // overloaded stream extraction operator; cannot be 20 // a member function if we would like to invoke it with 21 // cin >> somePhoneNumber; 22 istream &operator>>( istream &input, PhoneNumber &number ) 23 { 24 25 26 27 28 29 30 input.ignore(); // skip ( input >> setw( 3 ) >> number.areaCode; // input area code input.ignore( 2 ); // skip ) and space input >> setw( 3 ) >> number.exchange; // input exchange input.ignore(); // skip dash (-) input >> setw( 4 ) >> number.line; // input line return input; // enables cin >> a >> b >> c;
ignore skips specified number of characters from input (1 by default)
Input each portion of phone number separately
31 } // end function operator>>
CS-2303, C-Term 2010
Operator Overloading
22
Example 23.5 (concluded)
1 2 3 4 5 6 7 8 9 10 11 int main() 12 { 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // cout << phone invokes operator<< by implicitly issuing // the global function call operator<<( cout, phone ) cout << phone << endl; return 0; cout << "The phone number entered was: "; // cin >> phone invokes operator>> by implicitly issuing // the global function call operator>>( cin, phone ) cin >> phone; cout << "Enter phone number in the form (123) 456-7890:" << endl; PhoneNumber phone; // create object phone #include "PhoneNumber.h" // Fig. 22.5: fig22_05.cpp // Demonstrating class PhoneNumber's overloaded stream insertion // and stream extraction operators. #include <iostream> using std::cout; using std::cin; using std::endl;
Invoke overloaded >> and << operators to input and output a PhoneNumber object
27 } // end main
CS-2303, C-Term 2010
Operator Overloading
23
Questions?
CS-2303, C-Term 2010
Operator Overloading
24
Unary Operators
Can overload as
Non-static member function with no arguments. As a global function with one argument.
Argument must be class object or reference to class object.
Why non-static?
static functions only access static data
Not what is needed for operator functions
CS-2303, C-Term 2010 Operator Overloading 25
Example D & D 22.6
Overload '!' to test for empty string When compiler encounters
while (!s) if (!s)
it generates the call to
s.operator!()
Implemented as:
class String { public: bool operator!() const; };
CS-2303, C-Term 2010 Operator Overloading 26
Overloading Binary Operators
Non-static member function with one argument. or Global function with two arguments:
One argument must be class object or reference to a class object.
CS-2303, C-Term 2010
Operator Overloading
27
Overloading Binary Operators (continued)
If a non-static member function, it needs one argument.
class String { public: String & operator+=( const String &); };
By shorthand rule
y += z becomes y.operator+=( z )
CS-2303, C-Term 2010 Operator Overloading 28
Overloading Binary Operators
(continued) If a global function, it needs two arguments
class String { public: String & operator+=( String &, const String & ); };
By short-hand rule
y += z becomes operator+=(y, z)
CS-2303, C-Term 2010 Operator Overloading 29
Overloading Operators
On the previous slide, y and z are assumed to be String-class objects or references to Stringclass objects. There are two ways to pass arguments to the global function:
With an argument that is an object (this requires a copy of the object) or with an argument that is a reference to an object (this means the side effects of the function called to implement the overloaded operator can side-effect this object that is called-by-reference!)
CS-2303, C-Term 2010 Operator Overloading 30
Questions?
CS-2303, C-Term 2010
Operator Overloading
31
Next Time
Array Class
Deitel & Deitel
CS-2303, C-Term 2010
Operator Overloading
32