Вы находитесь на странице: 1из 5

Lesson 15: Function Overloading

Welcome to EasyCPlusPlus.com's free tutorial on C++ programming. This lesson covers overloaded functions. Function overloading provides a way to have multiple functions with the same name. Why would this be of benefit? Let's look at a simple example. Suppose it's needed to have a function that converts a temperature from Fahrenheit to Celsius. Prototype (Declaration): void ConvertFToC(float f, float &c);

Definition: void ConvertFToC(float f, float &c) { c = (f - 32.) * 5./9.; }

Now suppose that a Convert function is also needed to convert an integer Fahrenheit temperature to Celsius in the same program. One approach would be to give this function a new name, and perhaps to update the name of the "float" version as well. void fConvertFToC(float f, float &c); void iConvertFToC(int f, int &c);

That's not too bad. There are only two function names to keep track off. Now suppose that a higher precision, double, version is needed, or a version for data type short or long. void fConvertFToC(float f, float &c); void iConvertFToC(int f, int &c); void dConvertFToC(double f, double &c); void lConvertFToC(long f, long &c); void sConvertFToC(short f, short &c); As can be seen, this is quickly becoming a lexical nightmare. It is now necessary to remember five different function names for functions that essentially perform the same calculation. Someone reading or maintaining a program using these functions is bound to become quickly confused. It is not clear that exactly how exactly how each differs. Are only the data types

different or are there differences in calculation? Fortunately, function overloading provides an alternative. The same function name can be used for multiple functions provided each differs in the number or type of its parameters. For each call of the function, the compiler compares the number and type of the arguments in the call against the parameter lists of each version of the function. The compiler selects the appropriate version. This process is call function resolution. Here are definitions for each of the versions of ConvertFToC, and a small program that uses them. #include <iostream> using namespace std; void ConvertFToC(double f, double &c); void ConvertFToC(float f, float &c); void ConvertFToC(int f, int &c); int main() { double df, dc; float ff, fc; int i_f,i_c; df = 75.0; ff = 75.0; i_f = 75; // The compiler resolves the correct // version of ConvertFToC based on // the arguments in each call cout << "Calling ""double"" version" << endl; ConvertFToC(df,dc); cout << df << " == " << dc << endl << endl; cout << "Calling ""float"" version" << endl; ConvertFToC(ff,fc); cout << ff << " == " << fc << endl << endl; cout << "Calling ""int"" version" << endl; //if is a reserved word

ConvertFToC(i_f,i_c); cout << i_f << " == " << i_c << endl << endl; }

void ConvertFToC(double f, double &c) { cout << "In ""double"" version" << endl; c = (f - 32.0) * 5. / 9.; } void ConvertFToC(float f, float &c) { cout << "In ""float"" version" << endl; c = (f - 32.0) * 5. / 9.; } void ConvertFToC(int f, int &c) { cout << "In ""int"" version" << endl; c = (f - 32) * 5. / 9.; }

The overloaded functions in the previous example differed in the type of their arguments. It is also possible to overload functions if their number of arguments differs. For example: float FindMax(float a, float b); float FindMax(float a, float b, float c); int FindMax(int a, int b); and so on.

Functions differing only in their return type cannot be overloaded. Since the returned value may be implicitly converted, the compiler cannot resolve which version the programmer intended to use. The following code causes a compilation error. int FindAverage(float a, float b, float c); //Returns a rounded "average" as an int float FindAverage(float a, float b, float c); //Returns the double average int main() { int avg; float a = 5.0; float b = 5.5; float c = 6.0; avg = FindAverage(a, b, c); return 0; }

The compiler cannot determine whether the programmer intended: 1) To use the float version of FindAverage and then truncate the return value and assign to avg. 2) To use the int version of FindAverage, which returns a rounded average as an int.

Cases where overloading should not be used 1) If the functions to be overloaded perform distinct operations, then overloading will mask this

uniqueness and make their proper use harder. Suppose there are two functions to find a minimum value, one for float arguments and another for integer arguments. Further suppose that the minimum value function for integers is to return either the minimum, or zero if the minimum is less than zero, while the minimum value function for floats returns the minimum regardless of sign. If they are implemented as overloaded functions then it is easy to forget the extra bound on the integer version. Use: int FindMinOrZero(int a, int b); float FindMin(float a, float b); //Or some similar name

Rather than: int FindMin(int a, int b); float FindMin(float a, float b);

This distinct functionality is more apparent using distinct identifiers. 2) A single function with default arguments can replace the overloaded functions. Suppose that an "integer" FindMax function is needed and that it can take either two or three arguments. Also, assume that if will return zero if all the arguments are negative. Use: float FindMax(float a, float b, float c = 0);

Rather than: float FindMax(float a, float b); float FindMax(float a, float b, float c); This results in only a single function to learn to use and to maintain. 3) Function templates offer a cleaner design. Function templates are covered in the next lesson. They offer a way to parameterize arguments that differ only by type. The net result is that a single function template can sometimes replace several overloaded versions of a function.

Вам также может понравиться