Functions and Procedural Abstraction part 2
3.4 Polymorphism and Overloading
C++ allows polymorphism, i.e. it allows more than one function to have the same name, provided all functions are either distinguishable by the typing or the number of their parameters. Using a function name more than once is sometimes referred to as overloading the function name. Here's an example:
#include<iostream>
using namespace std;
int average(int first_number, int second_number, int third_number);
int average(int first_number, int second_number);
/* MAIN PROGRAM: */
int main()
{
int number_A = 5, number_B = 3, number_C = 10;
cout << "The integer average of " << number_A << " and ";
cout << number_B << " is ";
cout << average(number_A, number_B) << ".\n\n";
cout << "The integer average of " << number_A << ", ";
cout << number_B << " and " << number_C << " is ";
cout << average(number_A, number_B, number_C) << ".\n";
return 0;
}
/* END OF MAIN PROGRAM */
/* FUNCTION TO COMPUTE INTEGER AVERAGE OF 3 INTEGERS: */
int average(int first_number, int second_number, int third_number)
{
return ((first_number + second_number + third_number) / 3);
}
/* END OF FUNCTION */
/* FUNCTION TO COMPUTE INTEGER AVERAGE OF 2 INTEGERS: */
int average(int first_number, int second_number)
{
return ((first_number + second_number) / 2);
}
/* END OF FUNCTION */
Program 3.4.1
This program produces the output:
The integer average of 5 and 3 is 4.
The integer average of 5, 3 and 10 is 6.
(BACK TO COURSE CONTENTS)
3.5 Procedural Abstraction and Good Programming Style
One of the main purposes of using functions is to aid in the top down design of programs. During the design stage, as a problem is subdivided into tasks (and then into sub-tasks, sub-sub-tasks, etc.), the problem solver (programmer) should have to consider only what a function is to do and not be concerned about the details of the function. The function name and comments at the beginning of the function should be sufficient to inform the user as to what the function does. (Indeed, during the early stages of program development, experienced programmers often use simple "dummy" functions or stubs, which simply return an arbitrary value of the correct type, to test out the control flow of the main or higher level program component.)
Developing functions in this manner is referred to as functional or procedural abstraction. This process is aided by the use of value parameters and local variables declared within the body of a function. Functions written in this manner can be regarded as "black boxes". As users of the function, we neither know nor care why they work.
(BACK TO COURSE CONTENTS)
3.6 Splitting Programs into Different Files
As we have seen, C++ makes heavy use of predefined standard libraries of functions, such as "sqrt(...)". In fact, the C++ code for "sqrt(...)", as for most functions, is typically split into two files:
The header file "cmath" contains the function declarations for "sqrt(...)" (and for many other mathematical functions). This is why in the example programs which call "sqrt(...)" we are able to write "#include<cmath>", instead of having to declare the function explicitly.
The implementation file "math.cpp" contains the actual function definitions for "sqrt(...)" and other mathematical functions. (In practice, many C++ systems have one or a few big file(s) containing all the standard function definitions, perhaps called "ANSI.cpp" or similar.)
It is easy to extend this library structure to include files for user-defined functions, such as "area(...)", "factorial(...)" and "average(...)". As an example, Program 3.6.1 below is the same as Program 3.4.1, but split into a main program file, a header file for the two average functions, and a corresponding implementation file.
The code in the main program file is as follows:
#include<iostream>
#include"averages.h"
using namespace std;
int main()
{
int number_A = 5, number_B = 3, number_C = 10;
cout << "The integer average of " << number_A << " and ";
cout << number_B << " is ";
cout << average(number_A, number_B) << ".\n\n";
cout << "The integer average of " << number_A << ", ";
cout << number_B << " and " << number_C << " is ";
cout << average(number_A, number_B, number_C) << ".\n";
return 0;
}
Program 3.6.1
Notice that whereas "include" statements for standard libraries such as "iostream" delimit the file name with angle ("<>") brackets, the usual convention is to delimit user-defined library file names with double quotation marks - hence the line " #include"averages.h" " in the listing above.
The code in the header file "averages.h" is listed below. Notice the use of the file identifier "AVERAGES_H", and the reserved words "ifndef" ("if not defined"), "define", and "endif". "AVERAGES_H" is a (global) symbolic name for the file. The first two lines and last line of code ensure that the compiler (in fact, the preprocessor) only works through the code in between once, even if the line "#include"averages.h"" is included in more than one other file.
Constant and type definitions are also often included in header files. You will learn more about this in the object-oriented part of the course.
#ifndef AVERAGES_H
#define AVERAGES_H
/* (constant and type definitions could go here) */
/* FUNCTION TO COMPUTE INTEGER AVERAGE OF 3 INTEGERS: */
int average(int first_number, int second_number, int third_number);
/* FUNCTION TO COMPUTE INTEGER AVERAGE OF 2 INTEGERS: */
int average(int first_number, int second_number);
#endif
averages.h
Finally, the code in the implementation file "averages.cpp" is as follows:
#include<iostream>
#include"averages.h"
using namespace std;
/* FUNCTION TO COMPUTE INTEGER AVERAGE OF 3 INTEGERS: */
int average(int first_number, int second_number, int third_number)
{
return ((first_number + second_number + third_number) / 3);
}
/* END OF FUNCTION */
/* FUNCTION TO COMPUTE INTEGER AVERAGE OF 2 INTEGERS: */
int average(int first_number, int second_number)
{
return ((first_number + second_number) / 2);
}
/* END OF FUNCTION */
averages.cpp
Note the modularity of this approach. We could change the details of the code in "averages.cpp" without making any changes to the code in "averages.h" or in the main program file.
|