You are on page 1of 24

Operator Overloading

Reading
Chapter 8

Lesson 22 - Operator Overload

Operators
There's many operators in C++ relational (doing comparisons) logical (joining conditions) arithmetic also, we recently learned about new and delete

Lesson 22 - Operator Overload

Different Behaviours
Some operators have multiple behaviours, depending on the context:
e.g. asterisk is multiplication or indirection, depending

on whether it's a binary or unary operator e.g. ampersand is address of, bitwise-AND, and reference

These operators can be considered overloaded, similar to functions, since they behave differently depending on the items on the right and left of

them You can overload operators yourself if you wish


Lesson 22 - Operator Overload

How to Overload an Operator


Need to write a class method that contains the

keyword operator between the return type and operator being overloaded
e.g. Time Time::operator + (Time n); Must be an operator in the C++ language Must be a class method (not really, but lets assume so

for now) This will then allow you to use that operator with that class in the context described by the parameters and return type

Lesson 22 - Operator Overload

Issues
Have to be careful about what the parameters and

return type are


What the parameters and return type are define the

context under which the overloaded operator will work and what it will do This way, you can get greater functionality out of your classes

You choose what you want the operator to do

Lesson 22 - Operator Overload

Parameters
You're always working with the current object (through the use of the this pointer, if necessary)
The parameter list will provide any additional objects or items beside the this pointer
In a binary operator, the this pointer is the LHS object

and the (only) parameter is the RHS object In a unary operator, it is assumed that the operator is on the left (prefix form) of the object and that there are no parameters

Lesson 22 - Operator Overload

Restrictions
Cant change precedence of operator Cant change number of operands needed by the

operator Cant overload


.
:: .* ?: (ternary conditional operator) sizeof

Lesson 22 - Operator Overload

Guidelines for Overloading Operators


Super-Major Rule #1: Dont confuse the users of the class. Others:
Use common sense. Dont overload an operator just for the sake of

having it. If you define arithmetic operators, maintain the usual arithmetic identities.

e.g. If you can do a b + b, it should equal a.

You should provide arithmetic operators only when they make

logical sense to users.

e.g. Allow adding date + 5 but not 5 + date or date1 + date2.

Look at http://www.parashift.com/c++-faq-lite/operator-

overloading.html#faq-13.9
Lesson 22 - Operator Overload

Overloading The Assignment Operator


Parameter: const reference to the object Return value: const reference to the object, which should likely be *this e.g.
const three_d &op2) { x = op2.x; // y = op2.y; // z = op2.z; // return *this; } & three_d::operator=(const three_d
These are integer assignments and the = retains its original meaning relative to them.

Lesson 22 - Operator Overload

Overloading Arithmetic Binary Operators


Parameter: const reference to the object or primitive data type on the right-hand side of the operator
The textbook doesnt use this convention and instead

just passes it by value

Return value: the object by value The *this object is the object on the left-hand side of the operator
This implies that you must have an object on the left-

hand side of the operator in order for this to work

We will cover the situation where you have a primitive data type on the left-hand side later when we learn about friend functions

Lesson 22 - Operator Overload

Example of Overloading an Arithmetic Binary Operator


three_d three_d::operator+(const three_d &op2) { three_d temp; temp.x = x + op2.x; // These are integer additions temp.y = y + op2.y; // and the + retains is original temp.z = z + op2.z; // meaning relative to them. return temp; }

Lesson 22 - Operator Overload

Overloading Arithmetic Prefix Unary Operators


A Prefix Unary Operator is one that has the object on

the right-hand side (e.g. ++obj) Parameter: none (since its unary and the object is on the right this time) Return value: the object The *this object is the object on the right-hand side of the operator

Lesson 22 - Operator Overload

Example of Arithmetic Prefix Unary Operator Overloading


three_d &three_d::operator++() { x++; // increment x, y, and z y++; z++; return *this; }

Lesson 22 - Operator Overload

Overloading Arithmetic Postfix Unary Operators


What if you want to overload a postfix unary operator

(i.e. one that has the object on the left-hand side)? Theres a special case that is used for this
Use a dummy int parameter that you ignore

When used with a unary operator that can be postfix,

this automatically indicates to the compiler that it should be postfix

Return const object by value

Lesson 22 - Operator Overload

Example of Arithmetic Postfix Unary Operator Overloading


const three_d three_d::operator++(int) { three_d temp; x++; // increment x, y, and z y++; z++; temp.x = x; temp.y = y; temp.z = z; return temp; }

Lesson 22 - Operator Overload

Overloading Relational Operators


==, <, >, etc.
Parameter: const reference to the object or primitive

data type on the right-hand side of the operator


Again, the textbook doesnt use this convention and

instead just passes it by value

Return true or false (as bool) The textbook returns int instead

Lesson 22 - Operator Overload

Example of Overloading a Relational Operator


e.g.
bool three_d::operator==(const three_d &op2) { if( (x == op2.x) && (y == op2.y) && (z == op2.z) ) return true; else return false; }

Lesson 22 - Operator Overload

Example

int main() { three_d a(1, 2, 3), b(10, 10, 10), c; a.show(); b.show(); c = a + b; // add a and b together, need to overload + and = c.show(); c = a + b + c; // add a, b and c together c.show(); c = b = a; // demonstrate multiple assignment c.show(); b.show(); ++c; // increment c c.show(); return 0; }

Lesson 22 - Operator Overload

More of the Example...


#include <iostream.h> class three_d { int x, y, z; // 3-D coordinates public: three_d() { x = y = z = 0; } three_d(int i, int j, int k) {x = i; y = j; z = k; } three_d operator+(const three_d &op2); const three_d &operator=(const three_d &op2); const three_d operator++(void); // prefix version of ++ void show(void) ; } ;

// Overload assignment const three_d & three_d::operator=(const three_d &op2) { x = op2.x; // These are integer assignments y = op2.y; // and the = retains its original z = op2.z; // meaning relative to them. return *this; } // Overload the prefix version of ++. const three_d three_d::operator++() { x++; // increment x, y, and z y++; z++; return *this; }

// Overload + three_d three_d::operator+(const three_d &op2) { three_d temp; temp.x = x + op2.x; // These are integer additions temp.y = y + op2.y; // and the + retains is original void three_d::show() temp.z = z + op2.z; // meaning relative to them. { return temp; cout << x << ", "; } cout << y << ", "; cout << z << "\n"; }

Lesson 22 - Operator Overload

Warning!!!!
If you check in various textbooks and on the Internet,

you will find many different uses of const and references for parameters and return types for overloaded operators and just as many statements that their way is the right way
The justification is usually missing, sooooo ...

Lesson 22 - Operator Overload

Justification about Parameters (Binary only)

1.

2.

Parameters should usually be const references if they are objects because you usually dont change the argument on the left or right of a binary operator in normal use so it should be const you shouldnt pass objects by value because its far less efficient than passing as a reference

Lesson 22 - Operator Overload

Justification about Return Values for Assignment


If the operation is changing the LHS operand, then

you are really affecting this so you need to return a const reference to the object (which is *this)
It makes sense because you are simply assigning to the

item on the left hand side so its already taken care of

Lesson 22 - Operator Overload

Justification about Return Values for Other Arithmetic Operators


Object is returned by value You have to create a new object (as a local variable)

that is assigned to. Then, a copy of the object is returned.


If you were to return a reference to the local variable, it

would be invalid as soon as the function returned. If you were to return *this, you would be changing the object on the right-hand side of the operator.

Lesson 22 - Operator Overload