The idea of overloading is to use the same name for more than one function in a class.
This can be useful when you have separate names for functions that do essentially the same thing, but differ only in the number or types of arguments required. For instance, anExternalInterface has member functions DisplayText(), DisplayRequest(), and DisplayNumber(). Wouldn't it be nice to be able to just call a function named Display() and have the compiler figure out which implementation to call based on the arguments provided?
C++ makes this fairly simple.
For instance, to the compiler, the following declarations represent separate and distinguishable member functions of anExternalInterface, despite having the same name:
void Display(const char *theText) const; void Display(const aRequest &theRequest) const; void Display(const float theNumber) const;
Once you have defined these, you can call them:
myExternalInterface.Display("Some text"); myExternalInterface.Display(theRequest); myExternalInterface.Display(1.5);
These statements compile and run without compiler or runtime errors. Control flows to the correct implementations without any special work on your part.
Overloading is as simple as that. (At least, the basics are.)
How the Compiler Finds the Right Function
The compiler's idea of the best match and your idea of the best match may not be the same if you have several functions that offer very similar argument types in the same order.
You have a few alternatives that can help keep your overloaded functions distinct. These will ensure that you get the results you expect:
Try to make sure that your overloaded function argument types are as distinct as possible. For instance
void SomeFunction(const int theFirst, const int theSecond, const long theThird);
and
void SomeFunction(const int theFirst, const long theSecond, const int theThird);
are very similar and can be difficult to resolve for a call such as
SomeFunction(3,4,5);
In this situation, you might reconsider the overload and simply provide a “lowest common denominator” that can deal with int or long for any argument:
void SomeFunction(const long theFirst, const long theSecond, const long theThird);
You can change the order of arguments to make the overload distinct. For instance
void SomeFunction(const const int theFirst, const int theSecond, char theThird); void SomeFunction(const int theFirst, long theSecond, char theThird);
could be replaced by
void SomeFunction(const int theFirst, const int theSecond, char theThird); void SomeFunction(char theThird, long theSecond, const int theFirst);
This would force a caller of the second function to make the call distinct by placing the character as the first argument rather than the last.
Keep the number of arguments low. One of the purposes of creating objects rather than procedural programs is to leverage the capability of the object to maintain internal state. There is nothing wrong with a sequence of calls such as
SomeObject.SetFirst(3); SomeObject.SetSecond(4); SomeObject.SetThird(5); SomeObject.DoSomething();
or
SomeObject.SetFirst(3.2); SomeObject.SetSecond("4.2"); SomeObject.SetThird(5); SomeObject.DoSomething();
These calls leverage overloading as well as the capability of the object to maintain internal state. When DoSomething() is called, it works with whatever values have been set by prior function calls on the object.
Keep in mind that C++ does not use the function's return value type as part of the signature. Because of this, the following two declarations have the same signature and will cause a compiler error:
void Display(const char *theText) const; int Display(const char *theText) const;
Overload Resolution
Default arguments can cause problems for overloading. For instance, imagine two functions for anExternalInterface with these signatures:
void Display(const char *theText) const; void Display ( const char *theText, const int thePadWidth = 12 ) const;
The compiler will find it difficult to tell whether
ExternalInterface.Display("Stuff");
means to call
void Display(const char *theText) const;
or
void Display ( const char *theText, const int thePadWidth = 12 ) const;
because the presence of a default value for the second argument leaves open the possibility that you intended to call the second function, but used only one argument. So the signature of the call matches both implementations.
The compiler will let you compile these functions into your class. However, when a program actually calls the function and only provides a literal string as an actual parameter, you get a compiler message that looks like this:
[C++ Error] Ambiguity between 'SAMSCalculator::anExternalInterface::Display (const char *) const' and 'SAMSCalculator::anExternalInterface::Display (const char *,const int) const'
Here, the compiler is telling you that it can't see the difference between the two functions (the overload is ambiguous). There is nothing you can do to change this except eliminate the default argument.
Instead of a default argument, provide these two functions:
void Display(const char *theText) const; void Display ( const char *theText, const int thePadWidth ) const;
Have the first function assume a “PadWidth” of 12.
18.220.253.4