-->

Previous | Table of Contents | Next

Page 478

didn't use the same local variable names. This in turn means that library functions can be improved, if necessary, without impacting existing code. This is true whether the library contains application code for reuse or is distributed as the runtime library associated with a compiler.

NOTE
A runtime library is a collection of compiled modules that perform common C, C++, and UNIX functions. The code is written carefully, debugged, and highly optimized. For example, the printf function requires machine instructions to format the various output fields, send them to the standard output device, and check to see that there were no I/O errors. Because this takes many machine instructions, it would be inefficient to repeat that sequence for every printf call in a program. Instead, a single, all-purpose printf function is written once and placed in the standard library by the developers of the compiler. When your program is compiled, the compiler generates calls to these prewritten programs rather than re-creating the logic each time a printf call occurs in the source code.

Variable scope of reference is the language feature that allows small C and C++ programs to be designed to perform standalone functions, yet also to be combined into larger utilities as needed. This flexibility is characteristic of UNIX, the first operating system to be built on the C language. As you'll see in the rest of the chapter, variable scope of reference also makes object-oriented programming possible in C++.

Overloading Functions and Operators in C++

Overloading is a technique that allows more than one function to have the same name. There are at least two circumstances in which a programmer might want to define a new function with the same name as an existing one:

In C, a function name can be reused as long as the old function name isn't within scope. A function name's scope of reference is determined in the same way as a data name's scope: A function that is defined (not just called) within the definition of another function is local to that other function.

When two similar C functions must coexist within the same scope, however, they cannot bear the same name. Instead, two different names must be assigned, as with the strcpy and strncpy functions from the standard library, each of which copies strings but does so in a slightly different fashion.

Page 479

C++ gets around this restriction by allowing overloaded function names. That is, the C++ language allows programmers to reuse function names within the same scope of reference, as long as the parameters for the function differ in number or type.

Listing 23.12 shows an example of overloading functions. This program defines and calls two versions of the printvar function, one equivalent to printnum in Listing 23.11 and the other to printchar.

Listing 23.12. An example of an overloaded function.


#include <stdio.h>

void printvar (int tmp)

{

   printf ("%d \n",tmp);

}



void printvar (char tmp)

{

   printf ("a \n",tmp);

}



void main ()

{

   int  numvar;

   char charvar;

   numvar = 5;

   printvar (numvar);

   charvar = `a';

   printvar (charvar);

}



The following is the output of this program when it is executed:


5

a

Overloading is possible because C++ compilers are able to determine the format of the arguments sent to the printvar function each time it is called from within main. The compiler substitutes a call to the correct version of the function based on those formats. If the function being overloaded resides in a library or in another module, the associated header file (such as stdio.h) must be included in this source code module. This header file contains the prototype for the external function, thereby informing the compiler of the parameters and parameter formats used in the external version of the function.

Standard mathematical, logical, and other operators can also be overloaded. This is an advanced and powerful technique that allows the programmer to customize exactly how a standard language feature will operate on a specific data structure or at certain points in the code. Great care must be exercised when overloading standard operators such as +, MOD, and OR to ensure that the resulting operation functions correctly, is restricted to the appropriate occurrences in the code, and is well documented.

Page 480

Functions Within C++ Data Structures

A second feature of C++ that supports object-oriented programming, in addition to overloading, is the ability to associate a function with a particular data structure or format. Such functions can be public (able to be invoked by any code), can be private (able to be invoked only by other functions within the data structure), or can allow limited access.

Data structures in C++ must be defined using the struct keyword and become new datatypes added to the language (within the scope of the structure's definition). Listing 23.13 revisits the structure of Listing 23.3 and adds a display function to print out instances of the license structure. Note the alternative way to designate comments in C++, using a double slash. This tells the compiler to ignore everything that follows on the given line only.

Also notice that Listing 23.13 uses the C++ character output function cout rather than the C routine printf.

Listing 23.13. Adding functions to data structures.


#include <iostream.h>

//             structure = new datatype

struct license {

        char name[128];

        char address[3][128];

        int zipcode;

        int height, weight, month, day, year;

        char license_letter;

        int license_number;



        void display(void)

Â// there will be a function to display license type structures

        };



// now define the display function for this datatype



void license::display()

{

   cout << "Name:    "  << name;

   cout << "Address: "  << address[0];

   cout << "         "  << address[1];

   cout << "         " << address[2] << " " << zipcode;

   cout << "Height:  " << height << " inches";

   cout << "Weight:  " << weight << " lbs";

   cout << "Date:    " << month << "/" << day  << "/" << year;

   cout << "License: " <<license_letter <<license_number;

}





main()

{

   struct license newlicensee;      // define a variable of type license

   newlicensee.name = "Joe Smith";  //  and initialize it

   newlicensee.address(0) = "123 Elm Street";

   newlicensee.address(1) = "";

   newlicensee.address(2) = "Smalltown, AnyState";

Previous | Table of Contents | Next