CIS 22 - Data Structures: Operator Overloading
What is
Operator Overloading?
When an existing
operator, such as + or =, is given the capability to operate on additional
data types, it is said to be overloaded.
It is possible
to overload the built-in C++ operators such as +, >=, and ++ so that they
invoke different functions depending on their operands. That is, the +
in a+b will call one function if a and b are integers, but will call a
different function if a and b are objects of a class you've created. Operator
overloading is a C++ convenience feature that can make your program easier
to write and to understand.
Why Overload
Operators?
The reason is
that you want to make your code easier to read. Suppose you want to add
two values of type airtime (represents time: 12:59) and to assign the result
to another airtime variable. It's considerably easier to understand what's
happening when you see
at3 = at1 +
at2;
than when the same operation is
expressed as
at3 = at1.sum(at2);
or the even less obvious
at3.sum(at1,
at2);
You
Could It with Functions.
Overloading
does not add any capabilities to C++. Everything you can do with an overloaded
operator you can also do with a function. However, by making your code
more intuitive, overloaded operators make your programs easier to write,
read, and maintain.
You might think
of overloaded operators as a way to transfer some of the labor from the
class user to class creator. If the class creator spends a little time
overloading operators for appropriate tasks, the class user can spend less
time writing the code that invokes this tasks, because the operations will
be more intuitive.
The
operatorX() Function.
Suppose
you want to overload the + for airtime objects so that
at3 = at1 +
at2;
has the same effect as
at3 = at1.sum(at2);
To write an equivalent of the sum()
member function that will enable the + sign to carry out the addition operation,
C++ uses a keyword operator,
which is followed by the operator itself, to form a function name. To overload
+ operator, the name is operator+().
Here is an operator+()
member function for the airtime class, in skeleton form:
airtime operator+(airtime
right)
{
// function body
}
Now, you might think you need to
invoke this member function in the ordinary way, like this:
at3 = at1.operator+(at2);
This actually works - it adds at2
to at1 and returns the result - but it does not gain much in terms of readability.
The payoff comes when you rearrange the syntax. The dot operator, the word
operator itself, and the parentheses surrounding the function argument
are not necessary. They can be removed, leaving only
at3 = at1 +
at2;
This syntax holds true for any
operator x.
1.
Example of class that overloads operators.
-
airtime0.h
-
airtime0.cpp
-
main0.cpp
Fine - Tuned Version :
-
airtime.h
-
airtime.cpp
-
main.cpp
2.
Comments
to the example.
You
Can't Overload Everything.
Only the predefined
set of C++ operators can be overloaded. The designer of a class may not
define new operator tokens.
| + | - | * | / | % | ^ | & | | |
| ~ | ! | , | = | < | > | <= | >= |
| ++ | -- | << | >> | == | != | && | || |
| += | -= | /= | %= | ^= | &= | |= | *= |
| <<= | >>= | [ ] | ( ) | -> | ->* | new | delete |
Fine
- Tuning for Overloaded Operators.
Various techniques
can be used to make overloaded operators safer and more efficient. Most
arguments should be const
and passed by reference, to avoid the creation of extraneous object copies.
The operators themselves should be const
whenever they do not modify the object that called them. The *this
expression allows the value of the object that called the operator to be
returned by reference, which again avoids the
creation of additional copies.
| Type of Overloaded Operator |
|
|
|
| Arithmetic (+, -, *, /) | by value | const reference | const |
| Assignment (=, +=, -=) | by reference (*this) | const reference | non-const |
| Comparison (<, ==) | by value (boolean) | const reference | const |
| Unary prefix (++, --) | by reference (*this) | none | non-const |
| Unary postfix (++, --) | by value | value (dummy int) | non-const |
| Unary (-, +) | by value | none | const |
| Subscript | by reference | value (integer) | non-const |
The following materials were used in creating the page:
Lafore, Robert. C++ Interactive course.
Michael Gorenburg - Spring '98