View
217
Download
1
Embed Size (px)
Citation preview
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
DCO10105 Object-Oriented Programming and Design
Lecture 10: Operator overload
Operator overloadAssociate object and reference returnMember and non-member operator overloadFriend function
-- By Rossella Lau
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
The operators can only be applied to basic data types
Basic operators other than . (member identification) and = (assignment) cannot be applied to classes
Some functions are similar to C++ operations, e.g., to check if two objects are equal, to output the contents of an object
Defining those functions as, e.g., equal() or print() are fine but inconsistent with basic data types
C++ supports operator overload to allow for consistency and thus, other flexibilities
A reason for operator overload
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Forms of operator overload
returnType operatorop(parameter list) [const]
E.g., int operator[](int i) const {return array[i];}
Almost all operators can be overloaded except for . .* :: ?: sizeof with some restrictions (Malik’s slides: 16:8-9)
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Overloading binary operators
Usually, Arithmetics: e.g.,
TheClass operator+(TheClass const & rhsObject) const Relational: e.g.,
bool operator==(TheClass const & rhsObject) const Compond operators: e.g.,
TheClass & operator+= (TheClass const & rhsObject) I/O operators: e.g.,
ostream & operator<< (ostream & TheClass const & theObject)
rhs – right hand side
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Operator overload for Complex numbers
A complex number: c = a + bi
Addition of two complex numbers: c3 = c1 + c2 = (a+bi) + (c+di) = (a+c) + (b+d)i
Checking if two complex numbers are equal: c1 = c2 if and only if a == c && b == d
c1 += c2 c1 = (a+c) + (b+d)i
Output in the form of: a + bi
Class Complex { private: double real; double imaginary; public: …… // operator overload: ……};
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Example of addition and equalComplex operator+ (Complex const & rhs) const { return Complex (getReal() + rhs.getReal(), (getImaginary()+rhs.getImaginary();}bool operator== (Complex const & rhs) const { return getReal() == rhs.getReal() && getImaginary() == rhs.getImaginary();}
To invoke, e.g.,: Complex c1(2,3), c2(3,5), c3;
c3 = c1 + c2;
If (c1 == c2) ……
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Form of Operator overload execution
One can imagine that internally, C++ interprets the above expressions as: c3 = c1.operator+(c2) and if (c1.operator==(c2))
c1 is the left hand side operand while c2 is the right hand side operand
c1, the object being invoked, does not need to be modified and therefore, the most appropriate prototype should be declared with const
c2, the right hand side object, does not need to be modified and therefore, the most appropriate prototype should be declared as a const reference parameter
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Example of compound addition
Complex & operator+= (Complex const & rhs) { setReal (getReal() + rhs.getReal()); setImaginary ((getImaginary() + rhs.getImaginary()); return *this;}To invoke, e.g.,:
Complex c1(2,3), c2(3,5);c1 += c2; c1, the object being invoked, or the associate object must be
modified and therefore cannot be declared with const The return data should be the associate object itself and therefore
the return type should be a reference & to reference for the associate object
The associate object is referred to as *this (this is a keyword and is a pointer)
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Example of insertion operator overload
ostream & (ostream & out, Complex const & complex) { cout << complex.getReal() << “ + ” << complex.getImaginary() << “i” << endl; return out;}To invoke, e.g.,:
Complex c1(2,3);cout << c1;
Note that this operator overload is not a member function of Complex; it must be defined outside the class definition
Imagine the execution form: cout.(c1), the associate object can never be in Complex type
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Member and non-member operator overload
Some Operator overloads can not be member functions when the left hand side operand is not in the type of the class
Indeed, member operator overload functions can be defined as non member function
E.g., Complex operator+(Complex const & lhs, Complex const & rhs);
There should be two parameters as there is not an associate object
To invoke the non-member operator overload is the same as to invoke a member operator overload function
Malik’s slides: 15:32-33
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Operator Overloading: Member Versus Nonmember
Certain operators must be overloaded as member functions and some must be overloaded as nonmember (friend) functions
The binary arithmetic operator + can be overloaded either way
Overload + as a member function Operator + has direct access to data members of one of the
objects Need to pass only one object as a parameter
Malik’s slide: 15:32
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Operator Overloading: Member Versus Nonmember (continued)
Overload + as a nonmember function
Must pass both objects as parameters
Could require additional memory and time to make a local copy of the data
For efficiency purposes, overload operators as member functions
Malik’s slide: 15:33
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
More examples for application bookShop
Add a function operator==() As a member function As a non-member function
Add a function operator<<()
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Operator overload for Donald’s family
Operations with two different types: Implement deposit() as a member operator+() and a non-
member operator+() Implement withdraw() as a member operator-() and a non-
member operator-()
Implement print() as operator<<()
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Assignment operator
Remember to overload the assignment operator if there is a pointer data member, otherwise the one generated by the compiler may not be as expected
Malik’s slides: 15:24-25
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Overloading the Assignment Operator Function Prototype:
const className& operator=(const className&);
Only one formal parameter
Formal parameter is usually a const reference to a particular class
Function return type is a constant reference to a particular class
Malik’s slide: 15:24
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Overloading the Assignment Operator (continued) Function Definition:
const className& className::operator=(const className& rightObject)
{ //local declaration, if any if (this != &rightObject) //avoid self-assignment { //algorithm to copy rightObject into this object } //Return the object assigned. return *this; } // Malik’s slide: 15:25
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Operator overload for unary operators
Malik’s slides: 15:26-31, 35
Examples in IntArray: int operator[](int i) const {return array[i];}
int & operator[](int i) {return array[i];}
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Overloading Unary Operators
To overload a unary operator for a class:
If the operator function is a member of the class, it has no parameters
If the operator function is a nonmember (friend), it has one parameter
Malik’s slide: 15:26
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Overloading ++ and --
The increment operator has two forms Pre-increment (++u) Post-increment (u++)
u is a variable, say of the type int
Pre-increment: the value of u is incremented by 1 before using u in an expression
Post-increment: the value of u is used in the expression before it is incremented by 1
Malik’s slide: 15:27
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Overloading the Pre-Increment Operator as a Member Function
Function Prototype:
className operator++();
Function Definition:
className className::operator++()
{
//increment the value of the object by 1
return *this;
} //Malik’s slide: 15:28
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Overloading the Pre-Increment Operator as a Nonmember Function
Function Prototype:
friend className operator++(className&);
Function Definition:
className operator++(className& incObj)
{
//increment incObj by 1
return incObj;
} // Malik’s slide: 15:29
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Overloading the Post-Increment Operator as a Member Function
Function Prototype:className operator++(int);
Function Definition:className className::operator++(int u)
{
className temp = *this; //use this pointer to copy
//the value of the object
//increment the object
return temp; //return the old value of the object
} // Malik’s slide: 15:30
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Overloading the Post-Increment Operator as a Nonmember Function
Function Prototype: friend className operator++(className&, int);
Function Definition: className operator++(className& incObj, int u)
{
className temp = incObj; //copy incObj into temp
//increment incObj
return temp; //return the old value of the object
} // Malik’s slide: 15:31
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Overloading the Subscript Operator//Overload the operator [] for constant arrays
const Type& className::operator[](int index) const
{
assert(0 <= index && index < arraySize);
return list[index]; //return a pointer of the
//array component
} Malik’s slide: 15:35
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Friend functions
When defining non-member operator overload functions, if the respective class does not provide accessors or mutators, friend should be declared in the class definition for the overload function
Malik’s slides: 15:11-12
However, it is not preferred, as the purpose of a class is to encapsulate details and hide data from the outside world, one should eliminate using friend function as much as possible
In most of the cases, if a class provides sufficient accessors and mutators, friend functions can be avoided
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Friend Functions of Classes
friend function: a function defined outside the scope of a class
A friend is a nonmember function
However, has access to private data members
To make a function friend to a class
The reserved word friend precedes the function prototype in the class definition
Malik’s slide: 15:11
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Friend Functions of Classes (continued)
The word friend appears only in the function prototype (in the class definition), not in the definition of the friend function
When writing the friend definition
The name of the class and the scope resolution operator are not used
Malik’s slide: 15:12
Rossella Lau Lecture 10, DCO10105, Semester B,2005-6
Summary
Operator overload provides consistent usage of operators for both basic data types and classes
The associate object of a function is referenced as *thisSometimes, return of a reference object for operator overload
is necessaryOperator overload can be a member or a non member
functionI/O operator overloads cannot be member functionsOperator overload may be required to be a friend function of a
class if it needs to access a private member of the class but friend function can be voided if respective accessors and mutators are defined in the respective class