


                                                             Chapter 10
                                                      VIRTUAL FUNCTIONS

      Once again we are into a completely new topic with terminology
      which will be completely new to you.  If you are new to object
      oriented programming, you should follow along in this chapter very
      carefully because every attempt has been made to define every
      detail of this new and somewhat intimidating topic.  However, if
      you are well versed in object oriented programming, simply learning
      to use C++, you may wish to skip the first four programs in this
      chapter and go directly to the example program named VIRTUAL5.CPP
      and continue from there to the end of the chapter.

      One term which must be defined is polymorphism, a rather large word
      that simply means similar when used in the context of object
      oriented programming.  Objects are polymorphic if they have some
      similarities but are still somewhat different.  We will see how it
      is used in the context of object oriented programming as we proceed
      through this chapter.

      We have already studied operator overloading and function
      overloading in this tutorial, and they are a subtle form of
      polymorphism since in both cases, a single entity is used to refer
      to two or more things.  The use of virtual functions can be a great
      aid in programming some kinds of projects as you will see in the
      next two chapters.


      A SIMPLE PROGRAM WITH INHERITANCE
      _________________________________________________________________

      Examine the example program named VIRTUAL1.CPP   ================
      for the basic program outline we will use for      VIRTUAL1.CPP
      all discussion in this chapter.  Since this      ================
      program has nothing to do with virtual
      functions, the name may be somewhat misleading.
      It is named VIRTUAL1.CPP because it is part of a series of programs
      intended to illustrate the use of virtual functions. The last
      program in this chapter will illustrate the proper use of virtual
      functions.

      The first program is very simple and you will recognize it as being
      somewhat similar to the programs studied in the last chapter except
      that this program is greatly simplified in order to effectively
      instruct you in the use of a virtual function.  You will notice
      that many of the methods from the last chapter have been completely
      dropped from this example for simplicity, and a new method has been
      added to the parent class, the method named message() in line 8.
      Throughout this chapter we will be studying the operation of the
      method named message() in the parent class and the derived classes.
      For that reason, there is a method named message() in the car class
      as well as in the new class named boat in lines 27 through 32.

                                                              Page 10-1
      
                                         Chapter 10 - Virtual Functions

      You will also notice that there is a lack of a method named
      message() in the truck class.  This has been done on purpose to
      illustrate the use of the virtual method, or if you prefer, you can
      refer to it as a virtual function.  You will recall that the method
      named message() from the parent class is available in the truck
      class because the method from the parent class is inherited with
      the keyword public included in line 19.  You will also notice that
      the use of the keyword public in lines 12 and 27 actually do
      nothing because the only method available in the parent class is
      also available in the derived classes.  There are no methods
      actually inherited.  Leaving the keyword in the header poses no
      problem however, so it will be left there for your study.

      The method named message() in the parent class and in the derived
      classes has been kept very simple on purpose.  Once again, we are
      interested in the technique of the virtual method rather than a
      long complicated example.

      The main program is as simple as the classes, one object of each
      of the classes is declared in lines 37 through 40 and the method
      named message() is called once for each object.  The result of
      executing the program indicates that the method for each is called
      except for the object named semi, which has no method named
      message().  As discussed in the last chapter, the method named
      message() from the parent class is called and the data output to
      the monitor indicates that this did happen since it displays
      "Vehicle message" for the object named semi.

      The data for the objects is of no concern in this chapter so all
      data is allowed to default to private type and none is inherited
      into the derived classes.  Some of the data is left in the example
      program simply to make the classes look like classes.  Based on
      your experience with C++ by now, you realize that the data could
      be removed since it is not used.

      After you understand this program, compile and execute it to see
      if your compiler gives the same result of execution.


      ADDING THE KEYWORD VIRTUAL
      _________________________________________________________________

      As you examine the next example program named    ================
      VIRTUAL2.CPP, you will notice that there is one    VIRTUAL2.CPP
      small change in line 8.  The keyword virtual has ================
      been added to the declaration of the method
      named message() in the parent class.

      It may be a bit of a disappointment to you to learn that this
      program operates no differently than the last example program.
      This is because we are using objects directly and virtual methods
      have nothing to do with objects, only with pointers to objects as
      we will see soon.  There is an additional comment in line 46
      illustrating that since all four objects are of different classes,

                                                              Page 10-2
      
                                         Chapter 10 - Virtual Functions

      it is impossible to assign any object to any other object in this
      program.  We will soon see that some pointer assignments are
      permitted between objects.

      After you are convinced that virtual functions, or methods, have
      nothing to do with actual objects, compile and execute this example
      program to see if your compiler results in the same output as that
      listed.


      USING OBJECT POINTERS
      _________________________________________________________________

      Examine the example program named VIRTUAL3.CPP   ================
      and you will find a repeat of the first program    VIRTUAL3.CPP
      but with a different main program.               ================

      In this program the keyword virtual has been
      removed from the method declaration in the parent class in line 8,
      and the main program declares pointers to the objects rather than
      declaring the objects themselves in lines 37 through 40.  Since we
      only declared pointers to the objects we find it necessary to
      allocate the objects before using them by using the new operator
      in lines 42 through 49.  Upon running the program, we find that
      even though we are using pointers to the objects we have done
      nothing different than what we did in the first program.  Upon
      execution, we find that the program operates in exactly the same
      manner as the first example program in this chapter.  This should
      not be surprising because a pointer to a method can be used to
      operate on an object in the same manner as an object can be
      manipulated.

      Be sure to compile and execute this program before continuing on
      to the next example program.  The observant student will notice
      that we failed to deallocate the objects prior to terminating the
      program.  As always, in such a simple program, it doesn't matter
      because the heap will be cleaned up automatically when we return
      to the operating system.


      A POINTER AND A VIRTUAL FUNCTION
      _________________________________________________________________

      The example program named VIRTUAL4.CPP is        ================
      identical to the last program except for the       VIRTUAL4.CPP
      addition of the keyword virtual to line 8 once   ================
      again.

      I hope you are not terribly disappointed to find that this program,
      including the keyword virtual, is still identical to the last
      program.  Once again we are simply using pointers to each of the
      objects, and in every case the pointer is of the same type as the
      object to which it points.  You will begin to see some changes in
      the next example program, so be patient, we are almost there.

                                                              Page 10-3
      
                                         Chapter 10 - Virtual Functions


      Once again, it would be best for you to compile and execute this
      program.

      The four previous programs were meant to instruct you in what
      virtual functions do not do.  The next two will show you what
      virtual functions do.


      A SINGLE POINTER TO THE PARENT CLASS
      _________________________________________________________________

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

      You will notice that this is another copy of our program with the
      keyword virtual omitted from line 8 and with a totally different
      main program.  In this program, we only declare a single pointer
      to a class and the pointer is pointing to the parent 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
      message() is.

      A little digression is in order to understand how we can use a
      pointer to one class to 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.

      We can apply the same thought process in C++ and say that if we
      have a pointer to a vehicle (remembering that a pointer is actually
      a reference), 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 car, we cannot use that pointer to reference any of the other
      classes including the vehicle class because the pointer to the car
      class is too specific and restricted to be used on any of the other
      classes.


      THE C++ POINTER RULE
      _________________________________________________________________

      The rule as given in C++ terms is as follows.  A pointer to a
      parent class can be used to point to an object of a derived class
      of that parent class, but a pointer to a subclass cannot be used

                                                              Page 10-4
      
                                         Chapter 10 - Virtual Functions

      to point to the parent class or to any of the other derived classes
      of the parent class.  In our program therefore, we are allowed to
      declare a pointer to the vehicle class which is the parent class,
      and use that pointer to refer to either the parent class or any of
      the subclasses.

      This is exactly what we do in the main program.  We declare a
      single pointer which points to the vehicle class and use it to
      point to 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 message() 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 message() which is a part of the vehicle superclass.
      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 the parent class because the pointer is of the type of
      the parent class.

      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 our first real virtual function.


      A REAL VIRTUAL FUNCTION
      _________________________________________________________________

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

      This program is identical to the last example program except that
      the keyword virtual is added to line 8 to make the method named
      message() a virtual function.  You will notice that the keyword
      virtual only appears in the parent class.  In this program, we will
      once again use the single pointer to the parent 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 virtual in line 8, this
      program acts entirely different from the last example program.

      Since the method named message() is declared to be a virtual method
      in its declaration in the parent class, anytime we refer to this
      method with a pointer to the parent class, we actually execute the
      method associated with one of the subclasses if there is a method
      available in the subclass and if the pointer is actually pointing
      to that subclass.  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 subclasses, but we are actually
      using a pointer of the parent class type to make the calls.

                                                              Page 10-5
      
                                         Chapter 10 - Virtual Functions


      You will notice that in lines 40, 44, 48, and 52, 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.  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 truck does not have a method named
      message(), so the system simply uses the method from the parent
      class to satisfy the message passed.  For this reason, a virtual
      function must have an implementation available in the parent class
      which will be used if there is not one available in one or more of
      the subclasses.  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.

      It is probably not obvious but the observant student will note that
      the structure of the virtual function in the parent and each of the
      subclasses is identical.  The return type and the number and types
      of the parameters must be identical for all since a single
      statement can be used to call any of them.


      IS THIS REALLY SIGNIFICANT?
      _________________________________________________________________

      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.

      If the keyword virtual 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.

      It should be pointed out that virtual functions are most useful
      when used in conjunction with dynamic allocation and pointers, and
      the proper operation of virtual functions depends on function name
      overloading.  This is one of the reasons we stressed the topic of
      function name overloading earlier.

      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.




                                                              Page 10-6
      
                                         Chapter 10 - Virtual Functions

      PROGRAMMING EXERCISES
      _________________________________________________________________


      1.   Modify VIRTUAL3.CPP to deallocate the objects prior to
           terminating the program.

      2.   Add a message() method to the truck class of VIRTUAL6.CPP to
           observe the use of the new method instead of defaulting to the
           parent class method.













































                                                              Page 10-7
