Download presentation
Presentation is loading. Please wait.
0
Introduction to C++ computers and programming
CMPT 129 © Janice Regan, CMPT 129, 2017
1
Operator Overloading Introduction
You can think of an operator as a ‘special’ function that is called in a different way (alternate syntax) from ordinary functions Operators *, /, +, -, %, ==, << etc. For example to call ‘special’ function * If we think of the call to the function as *(5,q) Think of the function name as * 5,q are the arguments Function * returns product of it’s arguments We have special syntax for the very commonly used ‘functions’ to implement operators *(5,q) is actually written 5*q within your code However, this is still executing code that looks similar to a function © Janice Regan, CMPT 129, 2017
2
Operator Overloading Perspective
Built-in operators e.g. *,/,+, -, = , %, ==, !=, << , > … Appropriate subset of operators work with each built in C++ type Implementation syntax: operator operand operator Now we are defining new types (classes). How do we make the operators work on the objects in our classes OVERLOADING!! Want to use the same syntax as for built in types when we use the operators we are used to using for built in types How do we define our functions to accomplish this? Remember always overload only functions which perform similar actions! © Janice Regan, CMPT 129, 2017
3
Overloading Basics To indicate the name of the operator to be overloaded the keyword operator followed by the operator itself replace the identifier for a typical function Formal parameters of the function are const, so that actual parameters holding operands cannot be modified by the operator Example Declaration (not correct yet): Rectangle operator +( const Rectangle& R1, const Rectangle& R2); Overloads + for two operands of type Rectangle © Janice Regan, CMPT 129, 2017
4
Overloading Basics This function is not a member function of the class, must access attributes using accessor functions in definition of the function The formal arguments are passed by reference for efficiency The function returns an object of type Rectangle. Rectangle operator +( const Rectangle& R1, const Rectangle& R2); © Janice Regan, CMPT 129, 2017
5
What to do with Non-const Object
Assume + for a Rectangle gives the smallest rectangle including the 2 rectangles we are adding, Can call member functions: We could evaluate R1+R2 then use the returned sum in an expression like (R1+R2).output(); Not a problem: R1+R2 is a single anonymous object, The output() function should not change the anonymous object, OK But (R1+R2).input(); modifies the anonymous object, The sum is replaced by the input value (not reasonable) So we would like to define the anonymous object that is returned as const so it cannot be changed © Janice Regan, CMPT 129, 2017
6
Implementation (not yet correct)
const Rectangle operator + ( const Rectangle& R1, const Rectangle& R2) { Rectangle R3; int minx = 0; int miny = 0; int maxx = 0; int maxy = 0; minx = min( R1.GetXLocation(), R2.GetXLocation() ); miny = min( R1.GetYLocation(), R2.GetYLocation() ); maxx = max( R1.GetXLocation()+R1.GetWidth()-1, R2.GetXLocation()+R2.GetWidth()-1 ); maxy = max( R1.GetYLocation()+R1.GetHeight()-1, R2.GetYLocation()+R2.GetHeight()-1 ); R3.SetWidth( maxx - minx + 1 ); R3.SetHeight( maxy - miny + 1 ); R3.SetXLocation( minx ); R3.SetYLocation( miny ); R3.SetColour( R1.GetBlockColour() ); return R3; } © Janice Regan, CMPT 129, 2017
7
What is missing from the implementation
The implementation on the previous slide is not associated with the class Rectangle. It is not a member function of the class Because it is not a member we use accessor functions to access the attributes (not efficient) Because it is not associated it does not properly implement the operator Two approaches OK: Make the operator a friend of the class BEST: Make the operator method a member of the class © Janice Regan, CMPT 129, 2017
8
Implementation : Friend
Rectangle operator + ( const Rectangle& R1, const Rectangle& R2) { Rectangle R3; int minx = 0; int miny = 0; int maxx = 0; int maxy = 0; minx = min( R1.xLocation, R2.xLocation ); miny = min( R1.yLocation, R2.yLocation ); maxx = max( R1.xLocation+R1.width-1, R2.xLocation+R2.width-1 ); maxy = max( R1.yLocation+R1.height-1, R2.yLocation+R2.height-1 ); R3.width = maxx - minx + 1; R3.height = maxy - miny + 1 ; R3.xLocation = minx; R3.yLocation = miny; R3.SetColour( R1.GetBlockColour() ); return R3; } © Janice Regan, CMPT 129, 2017
9
What is a Friend Function
A friend is associated with the class but is not a member of the class A friend can directly access the attributes of the class like a member can A friend is listed in the definition of the class friend Rectangle operator + ( const Rectangle& R1, const Rectangle& R2) ; BUT a friend breaks the encapsulation of the class, So friends should be used only when they are really needed. (operators using multiple types of objects) Here we have options, we can make this operator a member. Being a member is better. © Janice Regan, CMPT 129, 2017
10
Implementation : MEMBER
Rectangle operator + (const Rectangle& R2) const { Rectangle R3; int minx = 0; int miny = 0; int maxx = 0; int maxy = 0; minx = min( xLocation, R2.xLocation ); miny = min( yLocation, R2.yLocation ); maxx = max( xLocation+width-1, R2.xLocation+R2.width-1 ); maxy = max( yLocation+height-1, R2.yLocation+R2.height-1 ); R3.width = maxx - minx + 1; R3.height = maxy - miny + 1 ; R3.xLocation = minx; R3.yLocation = miny; R3.BlockColour = BlockColour; return R3; } © Janice Regan, CMPT 129, 2017
11
OTHER BINARY OPERATORS Arithmetic operators
We can use the same approach to create a member method for other binary operators like - % / * The approach can be used for binary operators that follow the pattern below An anonymous object is returned Constant object1 and constant object 2 are combined using the binary arithmetic operator All 3 objects of the same class © Janice Regan, CMPT 129, 2017
12
OTHER BINARY OPERATORS Assignment operators
We can use a common approach to create member methods for binary operators like = += -= /= *= %= The approach that can be used for binary assignment operators follows the pattern below A reference to an object is returned The values of the attributes of constant object2 replaces or is combined with the values of the attributes of object 1 using the binary operator All 3 objects of the same class © Janice Regan, CMPT 129, 2017
13
MyClass& MyClass::operator=(const MyClass &rhs) { // 1
MyClass& MyClass::operator=(const MyClass &rhs) { // 1. Deallocate any memory that MyClass is using internally // 2. Allocate some memory to hold the contents of rhs // 3. Copy the values from rhs into this instance // 4. Return *this Overloaded = Member Rectangle& Rectangle::operator=(const Rectangle &Rectangle2) const { width = Rectangle2.width; height = Rectangle2.height; xLocation = Rectangle2.xLocation; yLocation = Rectangle2.yLocation; blockColour = Rectangle2.blockColour; return *this; } © Janice Regan, CMPT 129, 2017
14
Overloading = Why return a reference
For the operator = and Rectangle objects A, B The argument of the operator = method is a reference to Rectangle. The result of A=B returns a reference to an object of type Rectangle. (recall from precedence evaluate = from right to left) Returning a reference allows A=B=C; (A = (B=C) ) Consider the expression B=C, C is passed to the method as a reference if B=C returns a reference ( B = C ) is a reference and can be used as the parameter of the method for A = (B=C) © Janice Regan, CMPT 129, 2017
15
overloading = How it works
What happens when an assignment operator is executed? Depends on details of implementation but usually something like Rectangle& Rectangle::operator=(const Rectangle &R2) Deallocate any memory that MyClass is using internally Allocate some memory to hold the contents of R2 Copy the values from R2 into this instance Return *this © Janice Regan, CMPT 129, 2017
16
THIS In the overloaded = method we have used the line of code return *this; The this pointer *this points at the object (instance of the class) that is making the call The return type of the method that receives a this pointer is a type of “reference to object” We can also use the this pointer inside the method to access the object calling the method © Janice Regan, CMPT 129, 2017
17
Overloading += const Rectangle& Rectangle::operator +=( const Rectangle &Rectangle2) { width = this->width + Rectangle2.width; height = this->height + Rectangle2.height; xLocation = this->xLocation + Rectangle2.xLocation; yLocation = this->yLocation + Rectangle2.yLocation; blockColour = Rectangle2.blockColour; return *this; } © Janice Regan, CMPT 129, 2017
18
Object->Attribute name
We have seen that to directly access the value of an attribute B of a given object A we use the notation A.B If we want to directly access the value of an attribute B of a reference (or pointer) to an object A we use the notation A->B © Janice Regan, CMPT 129, 2017
19
OTHER BINARY OPERATORS Relational operators
We can use a common approach to create a member methods for binary relational operators like < > <= >= == != The approach can be used for binary relational operators follows the pattern below A Boolean value (true or false) is returned The values of the attributes of constant object1 are compared to the values of the attributes of object 1 The 2 constant objects are of the same class © Janice Regan, CMPT 129, 2017
20
== operator for Rectangle MEMBER
bool Rectangle::operator==(const Rectangle& R2) { if ( width == R2.width && height == R2.height && xLocation == R2.xLocation && yLocation == R2.yLocation && blockColour == R2.blockColour) { return true; } else { return false;} // Sample only, may not need all attributes identical // if the definition of equal is different for the class } © Janice Regan, CMPT 129, 2017
21
OTHER BINARY OPERATORS << >>
We can use a common approach to create a member method for other binary operators >> and << These operators have First operand is predefined stream object (cout, fstream, ifstream, … ) Second operand is any literal string or variable. Second operand is constant for <<, not for >> The values of the attributes of object2 are printed to the stream (object 1 is the stream). The 2 objects combined are of different classes © Janice Regan, CMPT 129, 2017
22
Overloading = Why return a reference
For the operator << stream A and Rectangle object B The first argument of the operator << method is a reference to a stream. The result of stream << B returns a reference to an object of type stream. (recall from precedence << evaluates left to right) Returning a reference allows stream << B << C; ((A << B)<<C ) Consider the expression A<<B, B is passed to the method as a reference if A<<B returns a reference to a stream Since (A<<B) is a reference to a stream, it can be used as the parameter of the << method for (A<<B) << C © Janice Regan, CMPT 129, 2017
23
Overloaded friend <<
ostream& operator << (ostream& os, Rectangle& myRectangle) { os << "Height of block is " << myRectangle.height << endl; os << "length of block is " << myRectangle.length << endl; os << "Location of upper left corner ("; os << myRectangle.xLocation << ", " << myRectangle.yLocation << ")"<<endl; os << "Number of rectangles created is "; os << myRectangle.rectanglesCreated << endl; os << "Number of rectangles existing is "; os << myRectangle.rectanglesExisting << endl;; return os; } © Janice Regan, CMPT 129, 2017
24
Overloading << or >> Why a Friend
Example: for class Rectangle ostream& operator << (ostream& os, Rectangle& myRectangle) Cannot change order of method parameters or chaining does not work. Chaining means cout << B << C << D; First parameter has the same type as the object that can call the function for object.method() to work: cannot be made a member function of Rectangle therefore must be a friend © Janice Regan, CMPT 129, 2017
25
Unary OPERATORS We can a common approach to create a member method for unary operators like The approach can be used for unary arithmetic operators that follow the pattern below An anonymous object is returned The values of the attributes of constant object1 is modified by the unary operation and the results placed in the anonymous object Object 1 and the anonymous object are of the same type © Janice Regan, CMPT 129, 2017
26
Increment and Decrement
Each operator has two versions Prefix notation: ++x; Postfix notation: x++; Must distinguish in overload Standard overload method Prefix Add 2d parameter of type int Postfix Just a marker for compiler! Specifies postfix is allowed © Janice Regan, CMPT 129, 2017
27
Overload Array Operator, [ ]
Can overload [ ] for your class To be used with objects of your class Operator must return a reference! Operator [ ] must be a member function! © Janice Regan, CMPT 129, 2017
28
Other Possible Overloads
&&, ||, and comma operator Predefined versions work for bool types Recall: use "short-circuit evaluation" When overloaded no longer uses short-circuit Uses "complete evaluation" instead Contrary to expectations Generally should not overload these operators © Janice Regan, CMPT 129, 2017
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.