home *** CD-ROM | disk | FTP | other *** search
-
-
-
- Chapter 11
- MORE VIRTUAL FUNCTIONS
-
- This chapter will actually be a continuation of the topics
- covered in the last chapter but this will be a fuller explanation
- of what virtual functions are and how they can be used in a
- program. We will present a simple database program with a
- virtual function to show how it can be used, then we will go on
- to illustrate a more complex use of the virtual function in a
- manner that finally illustrates its utility and reason for
- existence.
-
-
- HOW TO START AN OOP PROJECT
- -----------------------------------------------------------------
- The observant student will notice that we begin our use of object
- oriented programming by identifying an object, or in this case, a
- class of objects and even some subordinate objects, which we
- completely define. When we get to the main program we then have
- a simple job with the remaining needs and they are completed
- using standard procedural programming techniques which we are
- familiar with. This is the way to begin any object oriented
- programming project, by first identifying a few objects that can
- be separated conveniently from the rest of the code, programming
- them, then writing the main program. It should be added that,
- for your first project using objects, do not try to make
- everything an object. Select a few objects and after gaining
- experience with object oriented programming techniques, use more
- objects on future projects. Most programmers use too many
- objects for their first project and write very obtuse,
- unreadable code.
-
-
- THE PERSON HEADER FILE
- -----------------------------------------------------------------
- Examine the file named PERSON.H for the ==================
- definition file for the person class. This PERSON.H
- class definition should cause you no problem ==================
- to understand since there is nothing new
- here. The only thing that should be mentioned about this class
- is that the protected mode is used for the variables so that they
- are readily available in the derived classes which will inherit
- this class.
-
-
- THE PERSON IMPLEMENTATION
- -----------------------------------------------------------------
- The implementation for the person class is ==================
- given here and it is a little strange in the PERSON.CPP
- way it is written and used. The intent of ==================
- this program is that the virtual method named
- display() in this file will never be used, but it is required by
-
- Page 11-1
-
- Chapter 11 - More Virtual Functions
-
- the C++ compiler to be used for a default in case some of the
- subclasses do not have this function available. In the main
- program we will be careful to never call this function due to the
- nature of the program we are writing. Keep in mind that C++
- requires an implementation of all virtual functions even if they
- are never used. In this case the message is obviously intended
- to be output as an error message.
-
- Be sure to compile this program prior to going on to the next
- class definitions.
-
-
- THE SUPERVISOR HEADER
- -----------------------------------------------------------------
- The file named SUPERVSR.H contains the class ==================
- definitions for the three derived classes, SUPERVSR.H
- supervisor, programmer, and secretary. These ==================
- were all placed in a single file for two
- reasons. The first reason is to simply illustrate to you that
- this can be done, and secondly, to allow some of the files to be
- combined on the disk and to require fewer compilations by you
- prior to executing the resulting program. This is actually a
- good way to combine these files since they are all derived
- classes of a common class. It is a matter of style or personal
- taste.
-
- You will notice that all three of these classes contain a method
- named display() and all have the same return value of void, and
- all have the same number of parameters as the parent class's
- method of the same name. All of this equality is required
- because they will all be called by the same call statement. You
- will also notice that the other method in each class has the same
- name, but different numbers and types of formal parameters which
- prevents this method from being used as a virtual method.
-
- The remainder of this file is simple and you should be able to
- read the code and understand it completely. Once again, this
- file cannot be compiled or executed.
-
-
- THE SUPERVISOR IMPLEMENTATION
- -----------------------------------------------------------------
- The file named SUPERVSR.CPP contains the ==================
- implementation for the three classes. If SUPERVSR.CPP
- you spend a little time studying the code, ==================
- you will find that each of the methods named
- init_data() simply initializes all fields to those passed in as
- the actual arguments in a very simple manner. The method named
- display(), however, outputs the stored data in different ways for
- each class since the data is so different in each of the classes.
- Even though the interface to these three methods is identical,
- the actual code is significantly different. There is no reason
- code besides output could not have been used, but the output is
-
- Page 11-2
-
- Chapter 11 - More Virtual Functions
-
- so visible when the program is executed that it was chosen for
- this illustration.
-
- This file should be compiled at this time in preparation for the
- next example program which will use all four classes as defined
- in these four files.
-
-
- THE FIRST CALLING PROGRAM
- -----------------------------------------------------------------
- The file named EMPLOYEE.CPP is the first ==================
- program that uses the classes developed in EMPLOYEE.CPP
- this chapter, and you will find that it is a ==================
- very simple program.
-
- We begin with an array of ten pointers, each pointing to the base
- class. As you recall from the last chapter, this is very
- important when using virtual functions, the pointer must point to
- the base class. The pointers that will be stored in this array
- will all point to objects of the derived classes however. When
- we use the resulting pointers to refer to the methods, the system
- will choose the method at run time, not at compile time as nearly
- all of our other programs have been doing.
-
- We allocate six objects in lines 16 through 39, initialize them
- to some values using the methods named init_data(), then assign
- the pointers to the members of the array of pointers to person.
- Finally, in lines 41 and 42, we call the methods named display()
- to display the stored data on the monitor. You will notice that
- even though we only use one method call in line 42, we actually
- send messages to each of the three methods named display() in the
- subclasses. This is true dynamic binding because if we were to
- change the values of some of the pointers in the array, we would
- then call different methods with the same pointers.
-
- Be sure to compile and execute this program before continuing on
- in this chapter. You will recall that the linking step requires
- you to combine several files in order to satisfy all system
- calls. After you have done that, we will use the same objects in
- another way to show how they can be reused.
-
-
- THE LINKED LIST CLASS
- -----------------------------------------------------------------
- Examination of the file named ELEMLIST.H will ==================
- reveal the definition of two more classes ELEMLIST.H
- which will be used to build a linked list of ==================
- employees to illustrate a more practical way
- to use the dynamic binding we have been studying in this chapter.
- The two classes were put in the same file because they work
- together so closely and neither is of much value without the
- other. You will notice that the elements of the linked list do
- not contain any data, only a pointer to the person class that we
-
- Page 11-3
-
- Chapter 11 - More Virtual Functions
-
- developed for the last program, so that the linked list will be
- composed of elements of the person class without modifying the
- class itself.
-
- There are two interesting constructs used here that must be
- pointed out before going on to the next program. The first is
- the partial declaration given in line 8 which allows us to refer
- to the class named employee_list before we actually define it.
- The complete declaration for the class is given in lines 22
- through 29. The second construct of interest is the friend class
- listed in line 17 where we give the entire class named
- employee_list free access to the variables which are a part of
- the employee_element class. This is necessary because the method
- named add_person() must access the pointers contained in
- employee_element. We could have defined an additional method as
- a part of employee_element and used this method to refer to the
- pointers but it was felt that these two classes work so well
- together that it is not a problem to open a window between the
- classes. We still have complete privacy from all other programs
- and classes declared as parts of this program.
-
- Note that the single method included in the employee_element
- class is implemented in inline code. Two of the methods of
- employee_list are still open so we need an implementation for
- this class.
-
-
- THE LINKED LIST IMPLEMENTATION
- -----------------------------------------------------------------
- The file named ELEMLIST.CPP is the ==================
- implementation for the linked list classes ELEMLIST.CPP
- and should be self explanatory if you ==================
- understand how a singly linked list operates.
- All new elements are added to the end of the current list. This
- was done to keep it simple but an alphabetic sorting mechanism
- could be added to sort the employees by name if desired.
-
- The method to display the list simply traverses the list and
- calls the method named display() in line 30 once for each element
- of the list.
-
- It is important for you to take notice that in this entire class,
- there is no mention made of the existence of the three derived
- classes, only the base class named person is mentioned. The
- linked list therefore has no hint that the three subclasses even
- exist, but in spite of that, we will see this class send messages
- to the three subclasses as they are passed through this logic.
- That is exactly what dynamic binding is, and we will have a
- little more to say about it after we examine the calling program.
-
-
-
-
-
- Page 11-4
-
- Chapter 11 - More Virtual Functions
-
- USING THE LINKED LIST
- -----------------------------------------------------------------
- At this time you should examine the example ==================
- program named EMPLOYE2.CPP for our best EMPLOYE2.CPP
- example of dynamic binding in this tutorial, ==================
- yet the program is kept very simple.
-
- This program is very similar to the example program named
- EMPLOYEE.CPP with a few changes to better illustrate dynamic
- binding. In line 7 we declare an object of the class
- employee_list to begin our linked list. This is the only copy of
- the list we will need for this program. For each of the
- elements, we allocate the data, fill it, and send it to the
- linked list to be added to the list where we allocate another
- linked list element to point to the new data, and add it to the
- list. The code is very similar to the last program down through
- line 40.
-
- In line 43 we send a message to the display_list() method which
- outputs the entire list of personnel. You will notice that the
- linked list class defined in the files named ELEMLIST.H and
- ELEMLIST.CPP are never informed in any way that the subclasses
- even exist but they dutifully pass the pointers to these
- subclasses to the correct methods and the program runs as
- expected.
-
- If you changed PERSON.H to use a pure virtual function, it will
- still work with this program just as we discussed earlier.
-
-
- WHAT GOOD IS ALL OF THIS?
- -----------------------------------------------------------------
- Now that we have the program completely debugged and working,
- suppose that we wished to add another class to the program. For
- example, suppose we wished to add a class named consultant
- because we wished to include some consultants in our business.
- We would have to write the class of course and the methods within
- the classes, but the linked list doesn't need to know that the
- new class is added, so it doesn't require any changes in order to
- update the program to handle consultant class objects. In this
- particular case, the linked list is very small and easy to
- understand, but suppose the code was very long and complex as
- with a large database. It would be very difficult to update
- every reference to the subclasses and add another subclass to
- every list where they were referred to, and this operation would
- be very error prone. In the present example program, the linked
- list would not even have to be recompiled in order to add the new
- functionality.
-
- It should be clear to you that it would be possible to actually
- define new types, dynamically allocate them, and begin using them
- even while the program was executing if we properly partitioned
- the code into executable units operating in parallel. This would
-
- Page 11-5
-
- Chapter 11 - More Virtual Functions
-
- not be easy, but it could be done for a large database that was
- tracking the inventory for a large retail store, or even for an
- airlines reservation system. You probably have little difficulty
- understanding the use of dynamically allocated memory for data,
- but dynamically allocating classes or types is new and difficult
- to grasp, but the possibility is there with dynamic binding.
-
-
- AN APPLICATION FRAMEWORK
- -----------------------------------------------------------------
- The example program named APPFRAM1.CPP ==================
- illustrates the method used to write an APPFRAM1.CPP
- application framework. If you do much ==================
- serious programming, you will encounter one
- because they provide so many benefits for the MS Windows
- programmer. There are application frameworks available for DOS
- too, so most programmers should be familiar with them.
-
- The class named CForm is the base class for our trivial but
- important example, and it consists of four methods but no data
- members. The diligent student will note that the method named
- display_form calls the other three members to actually do the
- work of displaying our little form on the monitor. There is
- nothing magic about this program except that it is the framework
- for a very interesting concept used by all of the application
- frameworks currently available. Note that three of the methods
- are declared as virtual in lines 8 through 10.
-
- The interesting part occurs when we inherit the class into our
- new class named CMyForm in line 22 and write new methods for two
- of the base class methods. We have inherited as much
- functionality from the base class as we liked and wrote new
- methods for those that didn't serve our purpose as originally
- written. When we finally execute an object of the new class in
- line 34 of the main program, we do indeed use part of the base
- class, and override those parts that we explicitly wrote methods
- for.
-
- This is not too appealing in such a simple example, but if we
- consider how this is used in a real application framework, it is
- a very useful construct. The writer of an application framework
- will write a complete program that does all of the necessary
- housekeeping and windows maintenance chores and partition it in a
- number of virtual methods much like we did here. Of course, the
- framework will be composed of a large body of code to do all of
- those chores. In much the same manner that we picked which parts
- of this little form display program we wished to use and which to
- override, we pick those parts of the framework that we wish to
- keep as is and override those parts that we wish change. A large
- body of code is therefore already written for us and ready for
- our use.
-
-
-
- Page 11-6
-
- Chapter 11 - More Virtual Functions
-
- The application framework can include many other preprogrammed
- functions ready for our use, such as editor code for edit
- windows, data verification code for dialogue windows, and ready
- to use message window code. You will find it to be a very
- rewarding study to spend time examining the capabilities of one
- or more of the commercially available application frameworks.
-
-
- A PURE VIRTUAL FUNCTION
- -----------------------------------------------------------------
- The example program named APPFRAM2.CPP ==================
- illustrates a pure virtual function. A pure APPFRAM2.CPP
- virtual function is declared by assigning the ==================
- value of zero to the function as illustrated
- in line 9. A class containing one or more pure virtual functions
- cannot be used to define an object. The class is therefore only
- useful as a base class to be inherited into a useable derived
- class. It is sometimes called an abstract class.
-
- Every derived class must include a function for each pure virtual
- function that is inherited from the base class. This assures
- that there will be a function available for each call and none
- will ever need to be answered by the base class, which it cannot
- do since it does not have an implementation for a pure virtual
- function. You cannot create an object of any class which
- contains one or more pure virtual functions, because there is
- nothing to answer a message if one is sent to the pure virtual
- method. The compiler will enforce the two rules mentioned in
- this paragraph. If a class inherits an abstract class without
- providing an override for the pure virtual function, then it too
- becomes an abstract class and cannot be used to define an object.
-
- You will notice that the present example uses an abstract base
- class which makes it illegal to use an object of the base class
- as we did in the last example program. For that reason, some of
- the main program is commented out.
-
- You will find abstract classes used in many commercially
- available libraries and in application frameworks. Be sure to
- compile and execute this program, then make some modifications to
- see what the compiler indicates if you try to violate some of the
- rules we have delineated here.
-
- PROGRAMMING EXERCISE
- -----------------------------------------------------------------
- 1. Add a new class named consultant to the files named
- SUPERVSR.H and SUPERVSR.CPP, then add code to EMPLOYE2.CPP to
- exercise the new class. Note that you do not need to
- recompile the linked list class in order to execute the new
- code and use the new class. Even without recompiling the
- linked list class it is capable of storing and passing the
- new class of data provided of course that the new class is
- referred to using a pointer to the parent class.
-
- Page 11-7
-