home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
-
- Chapter 10
- VIRTUAL FUNCTIONS
-
- Once again we are into a completely new topic with terminology
- which will be 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 these
- 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 base class and the derived classes.
-
- Page 10-1
-
- Chapter 10 - Virtual Functions
-
- 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.
-
- 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 base class is available in the truck class
- because the method from the base 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 base 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 base 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
-
- Page 10-2
-
- Chapter 10 - Virtual Functions
-
- 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,
- 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 sure that the fact that they are virtual functions,
- or methods, has nothing to do with the objects as they are
- instantiated, 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
-
- Page 10-3
-
- Chapter 10 - Virtual Functions
-
- 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.
-
- 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 ================
- actually 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 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
- message() is.
-
- 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.
-
- 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.
-
-
-
-
- Page 10-4
-
- Chapter 10 - Virtual Functions
-
- THE C++ POINTER RULE
- _________________________________________________________________
-
- 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 vehicle class
- which is the base class, and use that pointer to refer to objects
- of either the base class or any of the derived classes.
-
- 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 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 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 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 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 study our first virtual function.
-
-
-
- AN ACTUAL 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 base class, all classes that derive
- this class will have the corresponding method automatically
- declared virtual 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 virtual in line 8, this program acts
- entirely different from the last example program.
-
-
- Page 10-5
-
- Chapter 10 - Virtual Functions
-
-
- Since the method named message() is declared to be a virtual 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 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.
-
- 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 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 truck does not have
- a method named message(), 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 there is not one 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.
-
- 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 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.
-
-
- Page 10-6
-
- Chapter 10 - Virtual Functions
-
- 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.
-
-
-
- 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