chap10.htm

来自「Since the field of object oriented progr」· HTM 代码 · 共 306 行 · 第 1/2 页

HTM
306
字号
functions do not do. The next two will show you what virtual functions
do.

<P><B>A SINGLE POINTER TO THE PARENT CLASS</B>

<P>Example program ------> <B><A HREF="VIRTUAL5.CPP">VIRTUAL5.CPP</A></B>

<P>Examine the example program named VIRTUAL5.CPP where we almost use a
virtual method. Be just a little patient because we are almost ready to
use a virtual method.

<P>You will notice that this is another copy of our program with the keyword
<B>virtual </B>omitted from line 9 and with a totally different main program.
In this program, we only define a single pointer to a class and the pointer
is pointing to the base class of the class hierarchy. We will use the single
pointer to refer to each of the four classes and observe what the output
of the method named <B>message()</B> is.

<P>A little digression is in order to understand how we can use a pointer
which has been declared to point to one class, to actually refer to another
class. If we referred to a vehicle (in the real world, not necessarily
in this program), we could be referring to a car, a truck, a motorcycle,
or any other kinds of transportation, because we are referring to a very
general form of an object. If however, we were to refer to a car, we are
excluding trucks, motorcycles, and all other kinds of transportation, because
we are referring to a car specifically. The more general term of vehicle
can therefore refer to many kinds of vehicles, but the more specific term
of car can only refer to a single kind of vehicle, namely a car.

<P>We can apply the same thought process in C++ and say that if we have
a pointer to a <B>vehicle</B>, we can use that pointer to refer to any
of the more specific objects, and that is indeed legal in C++ according
to the definition of the language. In a like manner, if we have a pointer
to a <B>car</B>, we cannot use that pointer to reference any of the other
classes including the <B>vehicle </B>class because the pointer to the <B>car
</B>class is too specific and restricted to be used on any of the other
classes.

<P><B>THE C++ POINTER RULE</B>

<P>The rule as given in C++ terms is as follows. A pointer declared as
pointing to a base class can be used to point to an object of a derived
class of that base class, but a pointer to a derived class cannot be used
to point to an object of the base class or to any of the other derived
classes of the base class. In our program therefore, we are allowed to
declare a pointer to the <B>vehicle </B>class which is the base class,
and use that pointer to refer to objects of the base class or any of the
derived classes.

<P>This is exactly what we do in the main program. We define a single pointer
which points to the <B>vehicle </B>class and use it to point to objects
of each of the classes in the same order as in the last four programs.
In each case, we allocate the object, send a message to the method named
<B>message()</B> and deallocate the object before going on to the next
class. You will notice that when we send the four messages, we are sending
the message to the same method, namely the method named <B>message()</B>
which is a part of the <B>vehicle </B>base class. This is because the pointer
has a class associated with it. Even though the pointer is actually pointing
to four different classes in this program, the program acts as if the pointer
is always pointing to an object of the base class because the pointer is
of the type of the base class.

<P>The next program will finally do something you have not seen in any
C program or in any C++ program in this tutorial up to this point. After
you compile and execute the current program, we will go on to study our
first virtual function.

<P><B>AN ACTUAL VIRTUAL FUNCTION</B>

<P>Example program ------> <B><A HREF="VIRTUAL6.CPP">VIRTUAL6.CPP</A></B>

<P>We finally come to an example program with a virtual function that operates
as a virtual function and exhibits dynamic binding or polymorphism as it
is called. This is in the program named VIRTUAL6.CPP.

<P>This program is identical to the last example program except that the
keyword <B>virtual </B>is added to line 9 to make the method named <B>message()</B>
a virtual function. You will notice that the keyword <B>virtual </B>only
appears in the base class, all classes that derive this class will have
the corresponding method automatically declared <B>virtual </B>by the system.
In this program, we will once again use the single pointer to the base
class and allocate, use, then delete an object of each of the four available
classes using the identical code we used in the last program. However,
because of the addition of the keyword <B>virtual </B>in line 9, this program
acts entirely different from the last example program.

<P>Since the method named <B>message()</B> is declared to be a <B>virtual
</B>method in its declaration in the base class, anytime we refer to this
method with a pointer to the base class, we actually execute the method
associated with one of the derived classes. But this is true only if there
is a method available in the derived class and if the pointer is actually
pointing to that derived class. When the program is executed, the output
reflects the same output we saw in the other cases when we were actually
calling the methods in the derived classes, but now we are using a pointer
of the base class type to make the calls.

<P>You will notice that in lines 44, 48, 52, and 56, even though the code
is identical in each line, the system is making the decision of which method
to actually call based on the type of the pointer when each message is
sent. The decision of which method to call is not made during the time
when the code is compiled but when the code is executed. This is dynamic
binding and can be very useful in some programming situations. In fact,
there are only three different calls made because the class named <B>truck
</B>does not have a method named <B>message(),</B> so the system simply
uses the method from the base class to satisfy the message passed. For
this reason, a virtual function must have an implementation available in
the base class which will be used if one is not available in one or more
of the derived classes. Note that the message is actually sent to a pointer
to the object, but this is splitting hairs and should not be overly emphasized
at this time.

<P>It is probably not obvious, but the observant student will note that
the structure of the virtual function in the base class and each of the
derived classes is identical. The return type and the number and types
of the parameters must be identical for all functions, since a single statement
can be used to call any of them.

<P><B>IS THIS REALLY SIGNIFICANT?</B>

<P>This program probably does not seem to do much when you first approach
it, but the dynamic binding is a very useful construct and will be illustrated
in the next chapter with a rather simple program that uses the technique
of dynamic binding to implement a personnel list for a small company.

<P>If the keyword <B>virtual </B>is used, the system will use late binding
which is done at run time, but if the keyword is not included, early binding
will be used. What these words actually mean is that with late binding,
the compiler does not know which method will actually respond to the message
because the type of the pointer is not known at compile time. With early
binding, however, the compiler decides at compile time what method will
respond to the message sent to the pointer.

<P>Be sure to compile and execute this example program before continuing
on to the next chapter where we will see a practical example of the use
of this technique.

<P><B>PROGRAMMING EXERCISES</B>
<OL>
<LI>
Modify VIRTUAL3.CPP to deallocate the objects prior to terminating the
program.</LI>

<LI>
Add a <B>message()</B> method to the <B>truck </B>class of VIRTUAL6.CPP
to observe the use of the new method instead of defaulting to the parent
class method.</LI>
</OL>
<A HREF="chap11.htm">Advance to Chapter 11</A>

<P><A HREF="cpplist.htm">Return to the Table of Contents</A>
</BODY>
</HTML>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?