Overloading and Default Arguments
A UTOMATIC T YPE C ONVERSION AND O VERLOADING
Suppose that the following function definition occurs in your program and that you have not overloaded the function name mpg (so this is the only definition of a function called mpg).
double mpg(double miles, double gallons) //Returns miles per gallon.
{
return (miles/gallons);
}
If you call the function mpg with arguments of type int, then C++ will automatically convert any argument of type int to a value of type double. Hence, the following will output 22.5miles pergallon to the screen:
cout << mpg(45, 2) << " miles per gallon";
C++ converts the 45 to 45.0 and the 2 to 2.0 and then performs the division 45.0/2.0 to obtain the value returned, which is 22.5.
If a function requires an argument of type double and you give it an argument of type int, C++
will automatically convert the int argument to a value of type double. This is so useful and nat-ural that we hardly give it a thought. However, overloading can interfere with this automatic type conversion. Let’s look at an example.
SIGNATURE
A function’s ssssiiiiggnnggnnaaaattttuuuurrrreeee is the function’s name with the sequence of types in the parameter list, not including the const keyword and not including the ampersand, &. When you overload a func-tion name, the two definifunc-tions of the funcfunc-tion name must have different signatures using this def-inition of signature. (Some authorities include the const and/or ampersand as part of the signature, but we wanted a definition that works for explaining overloading.)
interaction of overloading and type conversion
04_CH04.fm Page 154 Wednesday, August 13, 2003 12:49 PM
Overloading and Default Arguments 155
Self-Test Exercises
Suppose you had (foolishly) overloaded the function name mpg so that your program contained the following definition of mpg as well as the one previous:
int mpg(int goals, int misses)
//Returns the Measure of Perfect Goals //which is computed as (goals - misses).
{
return (goals - misses);
}
In a program that contains both of these definitions for the function name mpg, the following will (unfortunately) output 43milespergallon (since 43 is 45-2):
cout << mpg(45, 2) << " miles per gallon";
When C++ sees the function call mpg(45, 2), which has two arguments of type int, C++ first looks for a function definition of mpg that has two formal parameters of type int. If it finds such a function definition, C++ uses that function definition. C++ does not convert an int argument to a value of type double unless that is the only way it can find a matching function definition.
The mpg example illustrates one more point about overloading: You should not use the same function name for two unrelated functions. Such careless use of function names is certain to even-tually produce confusion.
8. Suppose you have two function definitions with the following declarations:
double score(double time, double distance);
int score(double points);
Which function definition would be used in the following function call and why would it be the one used? (x is of type double.)
double finalScore = score(x);
9. Suppose you have two function definitions with the following declarations:
double theAnswer(double data1, double data2);
double theAnswer(double time, int count);
Which function definition would be used in the following function call and why would it be the one used? (x and y are of type double.)
x = theAnswer(y, 6.0);
156 Parameters and Overloading
■ RULES FOR RESOLVING OVERLOADING
If you use overloading to produce two definitions of the same function name with sim-ilar (but not identical) parameter lists, then the interaction of overloading and auto-matic type conversion can be confusing. The rules that the compiler uses for resolving which of multiple overloaded definitions of a function name to apply to a given func-tion call are as follows:
1. Exact match: If the number and types of arguments exactly match a definition (with-out any automatic type conversion), then that is the definition used.
2. Match using automatic type conversion: If there is no exact match but there is a match using automatic type conversion, then that match is used.
If two matches are found at stage 1 or if no matches are found at stage 1 and two matches are found at stage 2, then there is an ambiguous situation and an error message will be issued.
For example, the following overloading is dubious style, but is perfectly valid:
void f(int n, double m);
void f(double n, int m);
However, if you also have the invocation
f(98, 99);
then the compiler does not know which of the two int arguments to convert to a value of type double, and an error message is generated.
To see how confusing and dangerous the situation can be, suppose you add the fol-lowing third overloading:
void f(int n, int m);
With this third overloading added, you no longer get an error message, since there is now an exact match. Obviously, such confusing overloading is to be avoided.
The above two rules will work in almost all situations. In fact, if you need more pre-cise rules, you should rewrite your code to be more straightforward. However, the exact rules are even a bit more complicated. For reference value, we give the exact rules below. Some of the terms may not make sense until you read more of this book, but do not be concerned. The simple two rules given above will serve you well until you do understand the more complete rules.
1. Exact match as described earlier.
2. Matches using promotion within integer types or within floating-point types, such as short to int or float to double. (Note that bool-to-int and char-to-int conver-sions are considered promotions within integer types.)
3. Matches using other conversions of predefined types, such as int to double. 4. Matches using conversions of user-defined types (see Chapter 8).
04_CH04.fm Page 156 Wednesday, August 13, 2003 12:49 PM
Overloading and Default Arguments 157
Example
5. Matches using ellipses ... (This is not covered in this book, and if you do not use it, it will not be an issue.)
If two matches are found at the first stage that a match is found, then there is an ambig-uous situation and an error message will be issued.