Overview of Operator Overloading


Introduction

Until now, we have mostly performed manipulations on objects by calling member functions of the objects. This member function-call notation is cumbersome for certain kinds of classes (such as mathematical classes). Also, many common manipulations in C++ are typically performed with operators (e.g., input and output, comparisons, etc.).

We can use C++'s large set of built-in operators to specify common object manipulations. Enabling C++'s operators to work with objects is called operator overloading.

We have already used a couple of overloaded operators. For example, operator << is used for multiple purposes in C++: as the stream-insertion operator and as the left-shift operator. Similarly, >> is also overloaded; it is used both as the stream-extraction operator and as the right-shift operator.

Fundamentals of Operator Overloading

C++ enables the programmer to overload most operators to be sensitive to the context in which they are used. The compiler generates an appropriate function or member function call based on the operator's use.

To overload an operator, write a function definition; the function name must be the keyword operator followed by the symbol for the operator being overloaded.

To use an operator on class objects, that operator must be overloaded - with two exceptions. The assignment operator (=) may be used with two objects of the same class to perform a default memberwise assignment without overloading. The address operator (&) can can be used with objects of any class without overloading; it returns the address of the object in memory.

The point of operator overloading is to provide the same concise expressive power for user-defined data types that C++ provides with its rich collection of operators that work on built-in types.

Operator overloading is not automatic - the programmer must write operator overloading functions to perform the desired operations. Sometimes these functions are best made member functions; sometimes they are best as friend functions.

Restrictions on Operator Overloading

Here is the list of C++ operators that can be overloaded:

+ - * / % ^ & |
~ ! = < > += -= *=
/= %= ^= &= |= << >> >>=
<<= == != <= >= && || ++
-- ->* , -> [] () new delete
new[] delete[]            

There are a handful of C++ operators that cannot be overloaded:

. .* :: ?:

Some other restrictions that apply:

Overloaded Operators as Standalone Functions vs. Member Functions

The C++ standard specifies that overloaded operators (), [], -> and any assignment operator must be member functions of the class for which they are overloaded.

For operators other than those, overloaded operator functions can be member functions or standalone functions that are not part of a class.

When an operator function is implemented as a member, the leftmost operand must be a class object (or a reference to a class object) of the operator's class.

If the left operand of an overloaded operator is an object of a C++ standard library class or is not an object at all, then the operator function must be implemented as a standalone function. A standalone operator function is usually made a friend of the class to improve performance by avoiding the overhead of calls to accessor and mutator methods.