HPlogo HP C++ Programmer's Guide: HP 9000 Series Workstations and Servers > Chapter 3 Compiling and Executing HP C++ Programs

An Extensive Example

» 

Technical documentation

Complete book in PDF

 » Table of Contents

 » Index

This section describes one model for designing a typical kind of C++ program. There are many ways to design a program. The method described here illustrates an object-oriented approach that uses data hiding.

The discussion is organized according to the following topics:

  • data hiding using files as modules

  • linking

  • an example based on a lending library

Data Hiding Using Files as Modules

Most programs are made up of several separately compiled units, usually files. The term module refers to a file containing a variable or function declaration, a function definition, or several of these or similar items logically grouped together. Thus, a program usually consists of several modules.

A C++ service consists of the following:

  • The declaration of all the objects the service provides. This is called the interface.

  • The operations that the service performs with its objects. This is called the implementation of those objects.

The interface is usually in one or more header files, or .h files. The implementation is usually in one or more .C or .c files associated with the corresponding .h files. Code in an application using the service is sometimes called a client of the service. Client source code is usually in a .C or a .c file.

Suppose, for example, a simple lending library service is organized into two modules, library_ex.h and library_ex.C.

The source file for this program resides in the directory /usr/contrib/CC/Examples (or /opt/CC/contrib/Examples/library_ex for HP-UX 10.x C++ versions.) The interface module, library_ex.h, contains the declarations of the objects in the service. Perhaps these would be class types named library, book, borrower, and transaction. The implementation module, library.C, contains the function definitions for the objects in the interface. Examples of these might be function definitions for library::display_books () and library::add_book(book*). A client of the library service could then consist of code in a .C file such as use_library.C. The sample program at the end of this chapter (example 3-1) is organized in just this way.

This type of organization uses data hiding, since it allows you to make available to clients of the service only the names they need to know. You can hide information that a client need not know in the .C files, or, if necessary, keep the implementation in object file format (.o files) only.

This type of service also provides considerable flexibility. An implementation can consist of one or more .C files, and you can provide several different interfaces in the form of .h files.

The next section describes how the separate modules of the service can be linked together.

Linking

Just like a program consisting of a single source file, a program consisting of many separately compiled parts must be consistent in its use of names and types.

For instance, a name that is not local to a function or a class must refer to the same type, value, function, or object in every separately compiled part of a program. That is, there can only be one nonlocal type, value, function, or object in a program with that name.

An object may be declared many times, but it must be defined exactly once. Also, the types must agree exactly in all the declarations of the object. Constants, inline functions, and type definitions can be defined as many times as necessary, but they must be defined identically everywhere in the program.

The best way to ensure that the declarations in separate modules are consistent is to follow these steps:

  1. Use a #include in each of your .C implementation files and .C client files.

  2. Compile each .C or .c file with CC using the -c option. This step creates an object file with an .o suffix.

  3. Link the object files created in step 2 using CC. This step creates an executable file.

In example 3-1 of a library service, the use_library.C and library_ex.C files each contain the following line:

#include "library_ex.h"

You could generate an object file from library_ex.C using the following command:

CC -c library_ex.C

Similarly, you generate an object file from use_library.C using the following command line:

CC -c use_library.C

Finally, you link the object files to create an executable file named a.out, using the following command:

CC use_library.o library_ex.o

The Lending Library

This section presents a simple example of a C++ service. The example is not intended to be a realistic application, but it illustrates the organization and concepts that have been discussed in this section.

The service example is a lending library. Its principal objects correspond to the books in the library's collection (book) and people who are enrolled to borrow books (borrower). The service includes an interaction object (transaction), which associates a particular book with a particular borrower, and an object that contains book, borrower, and transaction objects (library). There is an abstract data type (list) from which all the other classes are derived, making it easier to handle lists of the various types of objects.

The interface for the service is in the file library_ex.h, which lists the declarations for the book, borrower, transaction, library, and list classes. The implementation for the service is in the file library_ex.C, which lists the definitions for the book, borrower, transaction, library, and list classes. A client application program is listed in use_library.C.

The source file for this program resides in the directory /usr/contrib/CC/Examples (or /opt/CC/contrib/Examples/library_ex for for HP-UX 10.x C++ versions.)

To use the lending library service, put your source files in the same directory and follow the steps described above.

To run the executable file, enter:

a.out

The rest of this chapter consists of Example 3-1, which shows the three files discussed above: library_ex.h, library_ex.C, and use_library.C.

Figure 3-3 Example 3-1. A C++ Service: library_ex.h, library_ex.C, and use_library.C

//---------------------------------------------------------------------

// library_ex.h  -- the interface for the lending library service

//---------------------------------------------------------------------

// This module is included in the library_ex.C module.

// Some functions declared in this file are defined in the

// library_ex.C module.  You must link the library_ex.C and

// use_library.C modules to create an executable file.

// The main() function is in the use_library.C module.

//---------------------------------------------------------------------

#include <stream.h>

//---------------------------------------------------------------------

class list                      // list is an abstract class

{

private:

     list* link ;               // the only data member is a

                                // pointer to a list object

public:

     list()

      { link = 0; }             // constructor

     list* add(list* p )

      { p->link = this; return p; }

                                // this inline function adds a new

                                // item as the first one on the list

      list* next()

      { return this->link; }    // this inline function returns the

                                // next link on the list

     virtual void display_item()

      { cout << "none yet"; }   // this virtual function is redefined for

                                // book, borrower, and transaction classes

     void display();            // this function calls display_item()

};

//---------------------------------------------------------------------

class book:public list         // book is derived from list

{

private:

    char* title;               // data members are strings for

    char* author;              // the book's title and author

public:

    book(char* t,char* a);     // constructor for a book

    book* add_book(book* b)    // adds a book to the list

         { return (book*)(this->add(b)); }

    void display_item()        // shows a book's title and author

         { cout << " " << title << " by " << author;}

};

//---------------------------------------------------------------------

//---------------------------------------------------------------------

class borrower:public list     // borrower is derived from list

{

private:

    char* last_name;           // data members are strings for

    char* first_name;          // name and address of borrower

    char* address;

public:

    borrower(char* l, char* f, char* a); // constructor for borrower

    borrower* add_borrower(borrower* b)

         { return (borrower*)(this->add(b)); }

                               // adds a borrower to the list

    void display_item()        // shows a borrower's name and address

          {cout << " " << first_name << " " << last_name 

                << " of " << address;}

};

//---------------------------------------------------------------------

class transaction:public list // transaction is derived from list; it

                              // is an interaction object that creates

                              // an association between two objects

{

private:

    borrower* person;         // person who borrowed the book

    book* a_book;             // book that was borrowed public:

public:

    transaction(borrower* p, book* b);  //constructor

    transaction* add_transaction(transaction* t)

         { return (transaction*)(this->add(t)); }

                              // adds a transaction to the list

    void display_item()       // shows the book on loan to a borrower

         { person->display_item(); cout << " borrowed" ;

           a_book->display_item(); }

};

//---------------------------------------------------------------------

//---------------------------------------------------------------------

class library  // a library object contains linked lists of book,

               // borrower, and transaction objects

{

private:

     book* books;              // these are pointers to the first

     borrower* borrowers;      // object of each type on the list

     transaction* transactions;

public:

     library()

         { books = 0; borrowers = 0; transactions =0; }

                              // initialize the lists to null pointers

     void add_book (book* b)

         { if (books == 0) books = b; else books=books->add_book(b);}

                              // adds a book to the library's collection

     void add_borrower( borrower* b)

         { if (borrowers == 0) borrowers = b;

           else borrowers=borrowers->add_borrower(b); }

                              // enrolls a borrower as a library patron

     void add_transaction (transaction* t)

         { if (transactions == 0) transactions = t;

           else transactions=transactions->add_transaction(t); }

                              // records a book borrowed by a borrower

     void  display_books()

         { books->display(); }

                              // show all books in the library

     void  display_borrowers()

         { borrowers->display(); }

                              // show all borrowers currently enrolled

     void  display_transactions()

         { transactions->display(); }

                              // show all books currently borrowed

};

//-------------------------------------------------------------------

//-------------------------------------------------------------------

// library_ex.C -- the implementation for the interface in

//                 the library_ex.h header file

//-------------------------------------------------------------------

// This module can be linked with a client file, for example, the

// use_library.C module, to create an executable file. The

// main() function should be in the client file.

//-------------------------------------------------------------------

#include "library_ex.h"

#include <string.h>



//-----------------display a list ----------------------------------

void list::display()

{

 list* root = this;            // start at the beginning of the list

 if (root == 0)

    cout << "\nnone right now "; // check for empty list

else

    while (root!=0)           // walk through list

    {

     root->display_item();    // calls a virtual function to display

                              // each item using the member

                              // function that corresponds to the

                              // type of this object

     cout << "\n";

     root=root->next();

    }

}

//-----------------construct a book ---------------------------------

book::book(char* t,char* a)

{

  title = new char [strlen(t) +1];  //allocate memory for title

  strcpy(title,t);                  //copy title

  author = new char [strlen(a) +1]; //allocate memory for author

  strcpy(author,a);                 //copy author

}

//-------------------------------------------------------------------

//-----------------construct a borrower---------------------------

borrower::borrower(char* f, char* l, char* a)

{

  first_name = new char [strlen(f) +1];

                                      //allocate memory for first name

  strcpy(first_name,f);               //copy first name

  last_name = new char [strlen(l) +1];

                                      //allocate memory for last name

  strcpy(last_name,l);                //copy last name

  address = new char [strlen(a) +1];  //allocate memory for address

  strcpy(address,a);                  //copy address

}

//---------------construct a transaction ----------------------------

transaction::transaction(borrower* p,book* b)

{

  person = p;

  a_book=b;

}





//---------------------------------------------------------------------

// use_library.C --things you can do with the library service

//---------------------------------------------------------------------

// This program demonstrates the use of a library service. It must

// be linked with library_ex.C to create an executable file.

//---------------------------------------------------------------------

#include "library_ex.h"

main()

{

// Create a library object named the_library

  library* the_library = new library();



// Create some borrowers and add them to the_library

  borrower* me = new borrower ("Tech","Writer","HP");

  borrower* mary = new borrower ("Mary","Hartman","TVLand");

  borrower* mickey = new borrower ("Mickey","Mouse","DisneyLand");

  the_library->add_borrower(me);

  the_library->add_borrower(mary);

  the_library->add_borrower(mickey);

// Create a few books for the_library

  book* one = new book ("The C Programming Language", "Kernighan and Ritchie");

  book* two = new book ("The French Chef","Julia Child");

  book* three = new book ("HP C++","Tech Writer");

  the_library->add_book(one);

  the_library->add_book(two);

  the_library->add_book(three);



// Create a few transactions for the_library

  transaction* first = new transaction (me,two);

  transaction* second = new transaction (mary,one);

  the_library->add_transaction(first);

  the_library->add_transaction(second);



// Interact with a user

  cout << "\n\nWelcome to the library!  ";

  char  answer = 'Y';

  while ((answer != 'Q') && (answer != 'q'))

{

  cout << "\n\nYou can do the following: \n";

  cout << "\nA   Display the Library Collection ";

  cout << "\nB   Display a List of Borrowers in the Library";

  cout << "\nC   Display the Books on Loan ";

  cout << "\nD   Add a Book to the Library Collection";

  cout << "\nE   Enroll a Borrower ";

  cout << "\nF   Borrow a Book ";

  cout << "\n\nWhat would you like to do?";

  cout << "\nPress A, B, C, D, E, F, or Q to quit.";

  cin >> answer;

  char c;

  cin.get(c);          // read newline

  char string1[80], string2[80], name1[80], name2[80], name3[80];

  switch (answer)

     {

      case 'A': case 'a':  // display the library collection

           {cout << "\nHere's a list of the books in the library :\n";

           the_library->display_books();

           break;}

      case 'B': case 'b': // display a list of borrowers in the library

           {cout << "\nHere's a list of the borrowers:\n";

           the_library->display_borrowers();

           break;}

      case 'C': case 'c': // display the books on loan

           {cout << "\nHere's a list of the books that are out:\n";

           the_library->display_transactions();

           break;}

      case 'D': case 'd': // Add a book to the library collection

           {cout << "\nWhat is the title of the book to be added ? ";

           cin.get(string1,80); // read characters up to newline

           cin.get(c);          // read newline character

           cout << "\nAnd what is the author's name? ";

           cin.get(string2,80);

           cin.get(c);

           book* newbook = new book (string1,string2);

           the_library->add_book(newbook);

           break;}

      case 'E': case 'e': // Enroll a borrower

           {cout << "\nPlease enter the first name of the borrower-- ";

           cin >> name1;

           cout << "And the last name? ";

           cin >> name2;

           cout << "And where is " << name1 << " "

                << name2 << " from? ";

           cin >> name3;

           borrower* newborrower = new borrower (name1,name2,name3);

           the_library->add_borrower(newborrower);

           break;}

      case 'F': case 'f': // Borrow a book

           {cout << "\nBorrowing a book";

           cout << "\nWhat is the title of the book?  ";

           cin.get(string1,80);

           cin.get(c);

           cout << "\nAnd what is the author's name?  ";

           cin.get(string2,80);

           cin.get(c);

           book* B = new book (string1,string2);

           cout << "\nPlease enter the first name of the borrower-- ";

           cin >> name1;

           cout << "\nAnd the last name? ";

           cin >> name2;

           cout << "\nAnd where is " << name1 << " "

                << name2 << " from? ";

           cin >> name3;

           borrower* C = new borrower (name1,name2,name3);

           transaction* D = new transaction (C,B);

           the_library->add_transaction(D);

           break;}

     }

}

}

//--------------------------------------------------------------------
© Hewlett-Packard Development Company, L.P.