Вы находитесь на странице: 1из 5

9/5/2010 Operator Overloading

7.1 Operator Overloading

Operator overloading refers to the ability to define a new meaning for an existing (built-in) "operator" The list of
"operators" includes mathematical operators(+, -, *, /, ++, etc), relational operators ( <, >, ==, etc), logical
operators (&&, ||, etc.), access operators ([], ->), assignment operator (=), stream I/O operators ( <<, >>),
type conversion operators and several others. While all of these operator have a predefined and unchangeable
meaning for the built-in types, all of these operators can be given a specific interpretation for different classes or
combination of classes. C++ is particularly generous in the flexibility given to programmers in extending these
built-in operators; not all object-oriented languages allow this.

There are a number of reasons why a class designer may decide to provide extensions to one or more of the
built-in operators:

natural, suggestive usage

the most natural way to convey the intended meaning of an operation may be through the predefined
operators. For example, in defining a class to represent complex or rational numbers the best way to
represent adding to complex numbers or adding two rational numbers is by giving a new (extended)
meaning to the "+" operator rather than to invent a member function with a suggestive name ("addTo").

semantic integrity

classes that have pointers to objects frequently need a specialized assignment operator in order to copy
the objects being pointed to. The failure to properly handle assignment, as was seen earlier with the String
class, leads to either memory leaks or run-time errors.

uniformity with base types

templates often impose requirements on their arguments that can only be met by both built-in types and
user defined types when the user defined types provided overloaded operations. For example, a Set
template may require that its instantiating type have an equality operator ("==") in order to implement the
test for membership in the Set.

In many cases, the use of overloaded operators servers some or all of these purposes simultaneously.

A simple example introducing operator overloading is a "safe" array of integers. The array is to be "safe" in the
sense that the subscripting operation will insure that the subscript is within bounds. If the subscript is out of
bounds, the program will terminate. The declaration of the safe array is:

class Array {
private:
int array[20];
public:
Array(int init = 0);
int& operator[](int i); // overloaded subscript operator
~Array();
};
people.cs.vt.edu/…/op.overloading.html 1/5
9/5/2010 Operator Overloading

In this case, the subscripting operator, referred to as "operator[]" is defined to take a single integer input
argument. The subscripting operator returns a reference to the subscripted element of the array after checking
that the element of the array exits. This class is intended to be used as follows:
Array a;

a[0] = 1;
a[1] = 1;
for (int i = 2; i < 20; i++) // compute first 20 Fibonnaci numbers
a[i] = a[i-1] + a[i-2];

The compiler, upon encountering the expression "a[0]" will check to see if the class of "a" (in this case Array)
contains a class-specific definition for the "[]" operator. Since the Array class contains such an overloaded
operator method, the compiler will arrange for code to generated that is the equivalent of:
a.operator[](0)

which matches with the definition of the method given in the Array class. Similarly, the statement:
a[i] = a[i-1] + a[i-2];

would be treated as:


a.operator[](i) = a.operator[](i-1) + a.operator[](i-2);

Since the overloaded subscript operator returns a reference (specifically an "int&"), it is legitimate to have the
subscript operator appear in an expression on the left-hand side of the assignment operator.

Notice that aside from its declaration, the Array object looks and feels like a built-in array type. The similarity
between them is also suggested by the following code that shows Arrays and built-in arrays being intermixed:

Array safe;
int regular[20];

// define contents of arrays safe and unsafe

regular[10] = safe[10];
safe[11] = regular[11];
safe[0] = safe[0] + regular[0]

The built-in array type and the Array act the same except that the Array will cause a clean and informative error
message when a subscript out-of-bounds problem arises.

The implementation of the operator[] method would be written as follows:

int& Array::operator[](int i) {
assert(0 <= i && i < 20);
return array[i];
}

Again notice that there is nothing "special" about the operator[] method, except that its name must be exactly as
written in order to communicate to the compiler that this method is, in fact, to be treated as an overloading of the
built-in "[]" operator for objects of the Array class.
people.cs.vt.edu/…/op.overloading.html 2/5
9/5/2010 Operator Overloading

Two safe arrays may be added or subtracted by overloading the "+" operator and the "-" operator. The interface
of the Array class would then be changed as follows:

class Array
private:
int array[20];
public:
Array();
int& operator[](int i); // subscript operator
Array& operator+(Array& other); // addition operator
Array& operator-(Array& other); // subtraction operator
~Array();
};

Notice that the addition and subtraction operators return a reference to an Array object that holds the result of
the addition. The two Array objects being added are not changed. Instead a new Array object is created and
returned by reference.

The Array addition operator allows the following usages:

Array a,b; // initialized to 0


Array one(1); // initialized to 1

// give values to arrays a and b

Array& c = a + b;
Array& d = a - b + one;

The first of the two assignment statements produces an array each of whose elements is the sum of the
corresponding elements in the two arrays "a" and "b". The second assignment shows that the overloaded addition
and substraction operators for the Array class can be used in more complicated expressions.

The compiler will, on encountering the expression "a + b" determine if there is a class specific overloading of the
addition operator. Since "a" and "b" are objects of the Array class and this class contains an "operator+" method
with matching argument types, the compiler will generate code that is the equivalent of:

a.operator+(b)

where the object ("a") on the left-hand side of the addition in the expression "a +"b plays the role of the called
object and the object ("b") on the right hand side plays the role of the argument value. Similarly, the statement:
d = a - b + one

will be compiled into code that is equivalent to:


Array& anonymous = a.operator-(b);
d =anonymous.operator+(one);

where the name "anonymous" is used here to refer to the object created dynamically by the subtraction operator.

people.cs.vt.edu/…/op.overloading.html 3/5
9/5/2010 Operator Overloading
The use of the default assignment operator in the Array class is sufficient. The default assignment operator simply
performs a bit-level copy from the source to the target object. In this case, assignments such as:

Array f, g;

// assign values to g

f = g;

will work as intended: the data in Array g will be copied to the data in Array f.

The implementation of the Array addition and subtraction operators is as follows:

Array& Array::operator+(Array& other) {


Array *c = new Array;
Array& result = *c;

for(int i = 0; i< 20; i++) result[i] = array[i] + other.array[i];

return result;
}

Array& Array::operator-(Array& other) {


Array *c = new Array;
Array& result = *c;

for(int i = 0; i< 20; i++) result[i] = array[i] - other.array[i];

return result;
}

Each operation allocates a new Array object that it will return by reference as its result. Because the variable "c"
is a pointer to an Array object (not an Array object itself), it is not possible to write "c[i]". Using the variable "c"
directly it would be necessary to write (*c)[i] instead. While this usage is correct, it is awkward to always
remember to first dereference the pointer before applying the subscript operator. Also the parenthesis are
necessary to insure that the dereference happens first, writing "*c[i]" is incorrect. Instead, the variable "result" is
defined as a reference to the newly allocated Array. Since result is a reference to an Array it is possible to write
"result[i]".

Exercises
1. Extend the Array class to include an operator that would allow each element of the array to be multiplied
by a given constant. For example:
Array a;
Array& b = a*6; // multiple each element by 6

2. Extend the Array class to include a test for equality operator that returns 1 if all elements of the two Array
objects are the same and 0 otherwise. For example:
Array a;
people.cs.vt.edu/…/op.overloading.html 4/5
9/5/2010 Operator Overloading
Array b;

// give values to a and b

if ( a == b) {// uses equality operator


// code for when they are equal
}

Last Updated: November 9, 1995 / kafura@cs.vt.edu

people.cs.vt.edu/…/op.overloading.html 5/5

Вам также может понравиться