📄 chap11.htm
字号:
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="Gordon Dodrill">
<META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (Win95; I) [Netscape]">
<TITLE>C++ Tutorial - Chapter 11</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<B>C++ Tutorial - Chapter 11</B>
<P><B><FONT SIZE=+3>M</FONT><FONT SIZE=+2>ORE</FONT><FONT SIZE=+3> V</FONT><FONT SIZE=+2>IRTUAL</FONT><FONT SIZE=+3>
F</FONT><FONT SIZE=+2>UNCTIONS</FONT></B>
<P>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.
<P><B>HOW TO START AN OOP PROJECT</B>
<P>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.
<P><B>THE PERSON HEADER FILE</B>
<P>Example program ------><B> <A HREF="PERSON.H">PERSON.H</A></B>
<P>Examine the file named PERSON.H for the definition file for the <B>person
</B>class. This 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 <B>protected </B>mode is used for the variables
so that they are readily available in the derived classes which will inherit
this class. Notice that the one method in this class, line 11, is declared
<B>virtual</B>.
<P><B>THE PERSON IMPLEMENTATION</B>
<P>Example program ------> <B><A HREF="PERSON.CPP">PERSON.CPP</A></B>
<P>The implementation for the <B>person </B>class is given here and it
is a little strange in the way it is written and used. The intent of this
program is that the virtual method named <B>display()</B> in this file
will never be used, but it is required by the C++ compiler so it can 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.
<P>Be sure to compile this program prior to going on to the next class
definitions.
<P><B>THE SUPERVISOR HEADER</B>
<P>Example program ------> <B><A HREF="SUPERVSR.H">SUPERVSR.H</A></B>
<P>The file named SUPERVSR.H contains the class definitions for the three
derived classes, <B>supervisor</B>, <B>programmer</B>, and <B>secretary</B>.
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.
<P>You will notice that all three of these classes contain a method named
<B>display(),</B> all have the same return value of <B>void</B>, 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 can 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.
<P>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.
<P><B>THE SUPERVISOR IMPLEMENTATION</B>
<P>Example program ------> <B><A HREF="SUPERVSR.CPP">SUPERVSR.CPP</A></B>
<P>The file named SUPERVSR.CPP contains the implementation for the three
classes. If you spend a little time studying the code, you will find that
each of the methods named <B>init_data() </B>simply initializes all fields
to those passed in as the actual arguments in a very simple manner.
<P>The method named <B>display(),</B> 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 so visible when the
program is executed that it was chosen for this illustration.
<P>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.
<P><B>THE FIRST CALLING PROGRAM</B>
<P>Example program ------> <B><A HREF="EMPLOYEE.CPP">EMPLOYEE.CPP</A></B>
<P>The file named EMPLOYEE.CPP is the first program that uses the classes
developed in this chapter, and you will find that it is a very simple program.
<P>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.
<P>We allocate six objects in lines 16 through 39, initialize them to some
values using the methods named <B>init_data()</B>, then assign the pointers
to the members of the array of pointers to <B>person</B>. Finally, in lines
41 through 44, we call the methods named <B>display() </B>to display the
stored data on the monitor. You will notice that even though we only use
one method call in line 43, we actually send messages to each of the three
methods named <B>display()</B> in the derived classes. 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.
<P>In order for this to work, the interface had to be identical for each
function, but the implementation could be different for each function.
Polymorphism consists of two root words, poly and morph. Poly means different
and refers to the implementation, and morph means the same which refers
to the interface.
<P>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.
<P><B>THE LINKED LIST CLASS</B>
<P>Example program ------> <B><A HREF="ELEMLIST.H">ELEMLIST.H</A></B>
<P>Examination of the file named ELEMLIST.H will reveal the definition
of two more classes 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.
<P>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 <B>person </B>class that we developed for the last program, so that
the linked list will be composed of elements of the <B>person </B>class
without modifying the class itself.
<P>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 <B>employee_list</B>
before we actually declare it. The complete declaration for the class is
given in lines 23 through 31. The second construct of interest is the friend
class listed in line 18 where we give the entire class named <B>employee_list</B>
free access to the variables which are a part of the <B>employee_element</B>
class. This is necessary because the method named <B>add_person()</B> must
access the pointers contained in <B>employee_element</B>. We could have
defined an additional method as a part of <B>employee_element</B> 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 of visibility
between the classes. We still have complete privacy from all other programs
and classes declared as parts of this program.
<P>Note that the single method included in the <B>employee_element</B>
class is implemented in inline code. Two of the methods of <B>employee_list</B>
are still undefined so we need an implementation for this class.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -