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:
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(); };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.
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 + onewill 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.
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]".
Array a; Array& b = a*6; // multiple each element by 6
Array a; 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