Function Overloading
C++ allows specification of more than one function of the same name in the same scope. These are called overloaded functions and are described in detail in Overloading. Overloaded functions enable programmers to supply different semantics for a function, depending on the types and number of arguments.
For example, a print function that takes a string (or char *) argument performs very different tasks than one that takes an argument of type double. Overloading permits uniform naming and prevents programmers from having to invent names such as print_sz or print_d. The following table shows what parts of a function declaration C++ uses to differentiate between groups of functions with the same name in the same scope.
Overloading Considerations
Function Declaration Element |
Used for Overloading? |
---|---|
Function return type |
No |
Number of arguments |
Yes |
Type of arguments |
Yes |
Presence or absence of ellipsis |
Yes |
Use of typedef names |
No |
Unspecified array bounds |
No |
const or volatile (see below) |
Yes |
Although functions can be distinguished on the basis of return type, they cannot be overloaded on this basis. Const or volatile are only used as a basis for overloading if they are used in a class to apply to the this pointer for the class, not the function's return type. In other words, overloading applies only if the const or volatile keyword follows the function's argument list in the declaration.
Example
The following example illustrates how overloading can be used. Another way to solve the same problem is presented in Default Arguments.
// function_overloading.cpp
// compile with: /EHsc
#include <iostream>
#include <math.h>
// Prototype three print functions.
int print( char *s ); // Print a string.
int print( double dvalue ); // Print a double.
int print( double dvalue, int prec ); // Print a double with a
// given precision.
using namespace std;
int main( int argc, char *argv[] )
{
const double d = 893094.2987;
if( argc < 2 )
{
// These calls to print invoke print( char *s ).
print( "This program requires one argument." );
print( "The argument specifies the number of" );
print( "digits precision for the second number" );
print( "printed." );
exit(0);
}
// Invoke print( double dvalue ).
print( d );
// Invoke print( double dvalue, int prec ).
print( d, atoi( argv[1] ) );
}
// Print a string.
int print( char *s )
{
cout << s << endl;
return cout.good();
}
// Print a double in default precision.
int print( double dvalue )
{
cout << dvalue << endl;
return cout.good();
}
// Print a double in specified precision.
// Positive numbers for precision indicate how many digits
// precision after the decimal point to show. Negative
// numbers for precision indicate where to round the number
// to the left of the decimal point.
int print( double dvalue, int prec )
{
// Use table-lookup for rounding/truncation.
static const double rgPow10[] = {
10E-7, 10E-6, 10E-5, 10E-4, 10E-3, 10E-2, 10E-1, 10E0,
10E1, 10E2, 10E3, 10E4, 10E5, 10E6
};
const int iPowZero = 6;
// If precision out of range, just print the number.
if( prec < -6 || prec > 7 )
return print( dvalue );
// Scale, truncate, then rescale.
dvalue = floor( dvalue / rgPow10[iPowZero - prec] ) *
rgPow10[iPowZero - prec];
cout << dvalue << endl;
return cout.good();
}
The preceding code shows overloading of the print function in file scope.
For restrictions on overloading and information on how overloading affects other elements of C++, see Overloading.