OO Concept: Overloading

Overloading is the reuse of the same symbol or function name for two or more distinct operations or functions. Whilst this may sound confusing, used carefully it helps to keep code transparent. Overloading can be used with operators and functions.

Operators

FORTRAN used a limited form of operator overloading, for example:- 1 + 2 and 1. + 2. Here the plus sign stands for addition, but in the first example, the addition is integer arithmetic whilst in the second it is floating point. As they both perform the same logical operation, and the compiler can be relied on to pick the appropriate physical operation, the overloading of the plus sign is far better than inventing separate symbols for each physical operation.

In C++, this concept is pushed much further. It has a large operator set and almost all of them can be overloaded by user functions when involving expressions with objects. So it would be possible to develop a matrix class and then define addition, multiplication and so forth for it. C++ considers [] array and () - function call as operators. So it is possible to write constructions like:-

     MyObj[]
and  MyObj()
and have C++ treat this as a call to MyObj's member functions. One place where the function operator is overloaded is in ROOT's TIter class. It not uncommon to see code similar to this:-
TIter(MyCollection) next;

...     next() ...
In this class the function operator just calls the Next member function so next() is the same as next.Next(), but looks less odd (possibly).

Functions

FORTRAN also overloads generic functions. For example MAX stands for a family of maximum functions, with the compiler selecting the right one depending on context. So:-
max( 3, 5 )
and
max( 3. ,5. )
in one case selecting the largest integer and in the other the largest real. Again C++ extends the overloading concept, allowing the user to overload functions. We have already seen a simple example of this in the OO topic Constructors & Destructors in which our Track class had 2 constructors:-
  Track::Track(Float_t mass, Float_t energy);
  Track::Track();
Constructors are frequently overloaded. C++ requires a default i.e. one to be used without any arguments, but many interesting constructors require the user to qualify the initial state. Sometimes a single constructor can serve both functions as C++ allows default arguments. We could declare our track constructor as:-
  Track::Track(Float_t mass = 0., Float_t energy = 0.);
and then create a track with:-
Track MyTrack(0.135);
and have the compiler call the constructor function with energy = 0. As it stands we would now be in trouble if we did:-
Track MyTrack;
as the compiler has a choice: either use the default constructor, or the other with both arguments set to zero.

A Word of Warning

As we have just seen, supplying defaults for some arguments allows the compiler has some freedom to match a function to a context. It has further freedom in that if it cannot find an exact match, and it checks both the number and type of the arguments and return value, it looks to see if it can convert the values its been given into a form that matches a function it has. Although this fuzzy matching reduces the number of functions that are needed it can get very complicated, so its wise not to overdo overloading!
Go Back to the The C++ Crib Top Page


If you have any comments about this page please send them to Nick West