Operation Overloading pm_jat@daiict.ac.in
Recap: Why do we need Operator Overloading? Operator based expressions are more readable: Compare a + b * c with plus(a, times(b, c))
Recap: What is Operator Overloading? Some different thoughts to understand- It is making of your class an operator aware, or making the operator aware of that class It is means of giving new meaning to an operator in certain context of usage Basically you define how the operator should behave if it is used with particular type of operand(s)
Recap: What is Operator Overloading? Suppose you have two complex objects c1 and c2, and want to express, their addition as : c1 + c2 The operation is add two operands c1 and c2, and type of left and right operands are complex objects Compiler is not able to resolve this operation till it is able to find such operation definition Since this is your class, you need to provide definition for this operation on this class objects
Some operators not necessarily need to be defined There are two operators that will work with user defined objects, even if you do not define any function for- The assignment operator (=) The assignment operator will do a member wise assignment of the data members of the class. The address operator (&) The address operator simply returns the address of the object in memory.
Source: Big C++, Page 605 Operators, you can overload
Operator Overloading Note that You can not redefine existing behavior of an operator You can not change precedence, associativity, or arity of an operator You can not invent new operator symbols
Recap: How do you overload an operator? Two ways: Define a global function or define a member function of the class. Define a global function named operator+ (to overload plus operator), have first parameter of type of left operand and second parameter as type of right operand (in most case type of both are going to be same) Though, here, you can have parameters by value; you should have const references
Recap When you have this function defined, and you write expression: c1 + c2 Compiler interprets this expression as function call operator+(c1, c2) The function Implementation defines actions that needs to be performed when such expression encounters
Operator Member function When define operator+ as member function, and write expression: c1 + c2 Then, the compiler would interprets it as function call c1.operator+(c2)
How compiler looks appropriate function for binding When you write expression: a + b Compiler attempts to translate this expression to a function call and binds it to appropriate function definition. First, compiler looks for a member function operator+ in class A, if finds, then translates above expression to a.operator+(b) If not then looks for a global function operator+, having two parameters of type A and B respectively, if finds then translates expression a+b to operator+(a,b) If still does not find; compiler raises error: no match for 'operator+' in a + b'
Operator Overloading Note that when you have operator overloading as member function, the function has only one parameter, that is right operand; object on which method is being invoked becomes left operand Whether you implement as global function or a member function, usage syntax remains same: a + b Which approach to follow?
Which approach to be followed? Following things needs to be kept in mind while deciding about it. A global function may not able to access private members of operand objects; however you can permit a global function to access private data of a class by making the function friend of the class However granting access is violation of basic encapsulation principles, and not a good object oriented design; Therefore, if private part is to be accessed, it should be implemented as a member function of the class If no access of private members are required then either is fine.
Similarly you can overload other operators overloaded for Complex Class Exercise: implement some more operators for Complex class Subtract: - Multiplication: * Add and Update: += Equality: ==
Some Operator Functions needs to be member function only For example function for overloading [], ->, = operators. This is to ensure that their first operand is lvalue
Overloading Assignment (=) operator Though not required for complex class; let us do, just to see how it is done. What should be the prototype for overloading assignment operator for Complex Class? Why return is required? Is returning reference OK?
Overloading Input >> and Output << Though, originally shift operators Almost always overloaded for I/O operations Overloaded exactly as the binary arithmetic operators Should be overloaded as global functions?
Extraction/Insertion operator concepts All following expression mean same, where, let us say a, and b are objects of some classcin >> a >> b; ((cin >> a ) >> b); operator>>(operator>>(cin, a), b); Assuming that, we define a global function, following is typical prototype of extraction operationistream& operator>>(istream&, T&); Similarly for insertionostream& operator<<(ostream&, const T&);
overloading >> operator To overload >> operator for complex class, define following function istream& operator>>(istream&, Complex&);. istream& operator>>(istream& in, Complex& c) { double r, i; in >> r >> i; c.set(r,i); return in; }
We have already seen how this function is called?. operator>>(cin, a); operator>>(cin, b); Or operator>>(operator>>(cin, a), b); Or (cin >> a ) >> b); Or cin >> a >> b;
overloading >> operator Note that we have implemented it as a global function approach The function can not access private part of the complex class in this function To enable it to access private part, make the function as friend of the class.
Make a function friend to allow a global function to access private part of the class
overloading >> operator You can not overload >> operator as member function of a class. Why? Recall that, in member function approach, left operand is object of the class for which the function is being defined; In the case of, cin >> a; left operand is object of istream class? And you can not add a function operator>>(complex&) to istream class!!
Complex Class definition
Complex Class Implementation
Complex class : a typical client code
Overloading Unary Arithmetic Operators Operators + - & * have both binary and unary forms To overload unary form, reduce the number of parameters by one For example Complex operator-(const Complex& c) { } Complex tmp(-c.getreal(), -c.getimag()); return tmp; A unary operator defined as a member function takes no arguments
Overload = operator for Student class Needs to overload because, it requires deep copying. However you can have added functionality that when you assign one student object to another, Id of target object does not get over-written
What Next? See how other operators are overloaded, typically Increment ++ /decrement -- operators Subscript [] operator Overloading Conversion (cast) Operators More interesting examples, Chapter-17, Big C++
Thanks