CSC 306 Introduction to Programming with C++

Overloading Functions in C++

Chapter 3.1, 3.3, 3.4, 3.6, 4.4


Objectives

Important Definitions


Procedural Abstraction and Good Programming Style

One of the main purposes of using functions is to aid in the top-down design of programs. The first step in this design process is to describe the general problem, without trying to implement any details. The problem is subdivided into progressively smaller sub-problems (tasks) until the problem is reduced to a series of tasks that are relatively simple to implement. During this process of decomposing the problem, the programmer only has to determine what each function needs to do and not yet how they actually operate to produce their results. Typically, both the function name and comments at the beginning of each function should be sufficient to inform the user as to what the function does. In this way, the programmer deals with one thing at a time; design the flow of execution first, and then implement the functions. Once the control flow is debugged and correct, the programmer can shift focus onto implementing the small functions to produce the expected result from their inputs; in other words, how they should operate.

Developing functions in this manner is referred to as procedural abstraction.

Perhaps an example will help to demonstrate top-down design; suppose you want to find the area of a circle with the radius the user provides and output the result.

  1. Start with a general description:
    // Determine the area of a circle from the user input radius and display the 
    // result.
    
  2. Decide with is required for this to work:
    // Determine the area of a circle from the user input radius and display the 
    // result.
    
    // Need mechanisms to get input from the user and output the result.
    // define what PI is in this case.
    
  3. Give description (not implementation) of the parts to the problem. Here, it is very helpful to give meaningful function names!
    // Determine the area of a circle from the user input radius and display the 
    // result.
    
    // Need mechanisms to get input from the user and output the result.
    // define what PI is in this case.
    
    // 1) Get the radius value from the user.. return of type double
    double askUser();
    // 2) Calculate the area of the circle given a radius input.. also return type double
    double calculateArea( double radius );
    // 3) Output the area, given the area as an argument.
    void displayArea( double area );
    
  4. Check for execution flow. Define the main function to perform these operations in the correct order, and with correct output:
    int main() {
      double inputRadius = 0.0, circleArea = 0.0;
      // 1) Get the radius value from the user
      inputRadius = askUser();
      // 2) Calculate the area of the circle with that radius
      circleArea = calculateArea( inputRadius );
      // 3) Output the area
      displayArea( circleArea );
    }
    
  5. Now, implement the simpler sub-problems:
    // 1) Get the radius value from the user.. return of type double
    double askUser() {
      double input;
      cout << "Please give the radius of the circle: ";
      cin >> input;
      cout << endl;
      return input;
    }
    
    // 2) Calculate the area of the circle given a radius input.. also return type double
    double calculateArea( double rad ) {
      return (PI * radius * radius); // area is PI * (radius squared)
    }
    
    // 3) Output the result
    double outputResult( double result ) {
      cout << "The area is = " << result << endl;
    }
    
  6. The final program:
    // Determine the area of a circle from the user input radius and display the 
    // result.
    
    // Need mechanisms to get input from the user and output the result.
    #include <iostream>;
    using namespace std;
    
    // define what PI is in this case.
    const PI = 3.1415926535;
    
    // 1) Get the radius value from the user.. return of type double
    double askUser() {
      double input;
      cout << "Please give the radius of the circle: ";
      cin >> input;
      cout << endl;
    
      return input;
    }
    
    // 2) Calculate the area of the circle given a radius input.. also return type double
    double calculateArea( double rad ) {
      return (PI * radius * radius); // area is PI * (radius squared)
    }
    
    // 3) Output the result
    double outputResult( double result ) {
      cout << "The area is = " << result << endl;
    }
    
    int main() {
      double inputRadius = 0.0, circleArea = 0.0;
      // 1) Get the radius value from the user
      inputRadius = askUser();
      // 2) Calculate the area of the circle with that radius
      circleArea = calculateArea( inputRadius );
      // 3) Output the area
      displayArea( circleArea );
    }
    
Designing a program using this top-down approach makes debugging easier as well, through a technique called scaffolding. With scaffolding, you can debug these functions under temporary conditions to check if they work as expected from two directions:
  1. When testing execution flow, you are concerned with whether main() calls askUser() correctly. From this perspective, the function askUser() is essentially a black box. You do not care how it generates its result, so you can implement the function as a stub---a simplified version of the final function encoding:

    double askUser() {  // implementing as a stub to return 4.5 for debugging
      return 4.5;       // an arbritrary value
    }
    
    or

    double askUser() {    // still in stub form and incomplete
      double input = 0.0;
      input = 4.5;
      return input;
    }
    

  2. To test and debug the implementation of calculateArea(), you can have main() be a driver---a "dummy" or "test" version to see if the function does what is expected given an expected value:

    int main() {  // this driver version is not complete but for debugging only!
      double area = calculateArea( 4.5 );
      cout << "area for 4.5 is " << area << endl;
    }
    
    Note that the implementation of the main() function was very simplified to check whether the function calculateArea(...) worked correctly.

There are significant advantages when using top-down design and scaffolding in being able to implement and debug smaller well-defined functions one at a time, rather than deal with the entire problem at once.

Polymorphism and Overloading Functions

C++ allows a surprising thing called polymorphism, which means that it allows more than one function to have exactly the same name, provided all functions are distinguishable either by the data types of the parameters or by the number of parameters. Using a function name more than once is referred to as overloading the function name. Here's an example in which two different functions are both named "average":

#include<iostream>
using namespace std;

/* Function declarations */
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) {
    int sum; //This is a local variable
    sum = first_number + second_number + third_number;
    return ( sum / 3);
}  
/* END OF AVERAGE FUNCTION ONE */
	
/* FUNCTION TO COMPUTE INTEGER AVERAGE OF 2 INTEGERS: */
int average(int first_number, int second_number) {
    int sum; //This is another local variable.
    sum = first_number + second_number;
    return ( sum / 2);
}
/* END OF AVERAGE FUNCTION TWO */
This program produces the output:

    The integer average of 5 and 3 is 4.

    The integer average of 5, 3 and 10 is 6.
These two functions, which are both named average, are distingushable because their number of input parameters differ.


Assignment Specifics

This assignment must be done individually!

Your assignment is to write a program with a set of overloaded functions with the name areaRect that, given various kinds of input, compute the area of rectangle. Put the definitions of all these functions after the main() function (the declarations must go beforehand, of course). There are five versions:

  1. Inputs: two non-negative doubles, one representing the length and the other representing the width of the rectangle. This version should return a non-negative double for the area.

  2. Inputs: two non-negative integers, one representing the length and the other representing the width. This version should return a non-negative integer for the area.

  3. Input: a single non-negative integer, representing both the length and the width. (So, areaRect(5) means to compute the area of a 5x5 rectangle... Yes, this is also called a square!) This version should return a non-negative integer for the area.

  4. Input: a single non-negative double, representing both the length and the width. (So, areaRect(5.5) means to compute the area of a 5.5x5.5 rectangle...) This version should return a non-negative double for the area.

  5. Inputs: four doubles (that can each be positive, negative, or zero) that represent the (x, y) coordinates of two opposite corners of the rectangle. For example, a call to areaRect(1.0, 2.0, 5.0, 4.0) would mean that you want to compute and return the area of the rectangle that looks like:

    This version should return a non-negative double for the area.
    Hint: You may want to use the fabs() function that returns the absolute value of a double from the cmath library.

Your program should prompt and receive from the user the inputs you need. i.e. ask the user for the dimensions for the rectangles for the first 4 functions, and the coordinates for the last function.

Some final notes:

When you are finished writing and testing your assignment, drop your source code, YourLastName_306A7.cpp, into the CSC306_A07 dropbox on the Academic server.


Back to Introduction to Computer Programming with C++ Homepage