Function Overloading
Function polymorphism is a neat C++ addition to C's capabilities. Although default arguments let you call the similar function by using varying numbers of arguments, function polymorphism, also known as function overloading, and let you use multiple functions sharing the similar name. The term "polymorphism" means having several forms, so, function polymorphism lets a function have several forms. As same, the expression "function overloading "take a meaning that you can attach more than one function to the similar name, therefore overloading the name. Both expressions boil down to the similar thing, but we will commonly use the expression function overloading, it sounds harder working. You could use function overloading to design a family of functions in which do essentially the similar thing, but using various argument lists.
Overloaded functions are analogous to verbs having more than one meaning. For instance, Miss Piggy could root at the ball park for the home team or she can root in the soil for truffles. A context (one hopes) tells you that meaning of roots is intended in every case. As same, C++ uses the context to decide that version of an overloaded function is intended.
The key to function overloading is a function's argument list, also known as the function signature. They have the same signature; the variable names don't matter if two functions use the similar number and types of arguments in the similar order. C++ enables you to describe two functions through the similar name gives in which the functions have different signatures. The signature can differ in the number of arguments or in the type of arguments, or both. For instance, you can describes a set of print() functions along with the subsequent prototypes:
void print( const char * str , int width); // #1
void print( double d, int width); // #2
void print( long l, int width); // #3
void print( const char * str); // #4
whenever you then use a print() function, a compiler matches your use to the prototype which has the similar signature:
print( "Pancakes", 15); // use #1
print( "Syrup"); // use #5
print(1999.0, 10); // use #2
print(1999,12); // use #4
print(1999L, 15); // use #3
For instance, print("Pancakes", 15) uses a string and an integer as arguments, and which matches prototype #1.
Whenever you use overloaded functions, be sure you use the proper argument categories in the function call. For instance, let consider the following statements.
unsigned int year = 3210;
print( year, 6);
Which prototype does the print () call match here? It does not match some of them! A lack of a matching prototype does not automatically rule out by using one of the functions, for c++ that will try to use standard type conversions to force a match. If, say, the only print () prototype were #2, the function call print (year, 6) would convert the year value to type double. Other than in the code there are three prototypes that take a number as the first argument, giving three various choices for converting year. Faced with this ambiguous condition, c++ rejects the function call as an error.
A few signatures which appear different from every other can't coexist. For instance, let consider these two prototypes:
double cube(double x);
double cube(double & x);
You may think this is a place you could use function overloading, to the function signatures appear to be different. But let consider things from the compiler's standpoint.
Assume you have code such this:
cout <<cube (x);
The x argument matches the double x prototype and the double &x prototype both. Therefore, the compiler has no way of knowing that function to use. Thus, to prevent such confusion, whenever it checks function signatures and the compiler considers a reference to a type and the type itself to be the similar signature.
The function matching process does discriminate among const and non-const variables. Let consider the subsequent prototypes:
void dribble (char * bits); //overloaded
void dribble ( const char *cbits); //overloaded
void dabble (char * bits ); //not overloaded
void drivel (const char *bits); //not overloaded
Where what several function calls would match:
const char p1[18] = "How is the weather?"
char p2[18] = "How is business ?"
dribble (p1); // dribble (const char *);
dribble (p2); // dribble (char *);
dabble(p1) ; // no match
dabble(p2); // dabble (char *);
drivel (p1); // drivel(const char *);
drivel(p2); // drivel(const char *);
A dribble() function has two prototypes, single for const pointer and one for regular pointers and the compiler selects one or the other depending on whether or not the actual arguments , other than the drivel() function matches calls with either const or non- const arguments . The reason for this difference in behavior among drivel () and dabble () is which it's valid to assign a non-const value to a const variable, but not conversely.
Remember that it's the signature, not the function type which enables function overloading. For instance, the following two declarations are incompatible.
Thus, C++ will not allow you to overload grounk() in this fashion. You could have various return types, other than just if the signatures also are different.
long grounk(int n, float m);
double grounk(float n, float m);