home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / tutorial / cpptutor / text / chap10.txt < prev    next >
Encoding:
Text File  |  1994-05-15  |  17.2 KB  |  348 lines

  1.  
  2.  
  3.  
  4.                                                        Chapter 10
  5.                                                 VIRTUAL FUNCTIONS
  6.  
  7. Once again we are into a completely new topic with terminology 
  8. which will be new to you.  If you are new to object oriented 
  9. programming, you should follow along in this chapter very 
  10. carefully because every attempt has been made to define every 
  11. detail of this new and somewhat intimidating topic.  However, if 
  12. you are well versed in object oriented programming, simply 
  13. learning to use C++, you may wish to skip the first four programs 
  14. in this chapter and go directly to the example program named 
  15. VIRTUAL5.CPP and continue from there to the end of the chapter.
  16.  
  17. One term which must be defined is polymorphism, a rather large 
  18. word that simply means similar when used in the context of object 
  19. oriented programming.  Objects are polymorphic if they have some 
  20. similarities but are still somewhat different.  We will see how 
  21. it is used in the context of object oriented programming as we 
  22. proceed through this chapter.
  23.  
  24. We have already studied operator overloading and function 
  25. overloading in this tutorial, and they are a subtle form of 
  26. polymorphism since in both cases, a single entity is used to 
  27. refer to two or more things.  The use of virtual functions can be 
  28. a great aid in programming some kinds of projects as you will see 
  29. in these two chapters.
  30.  
  31.  
  32. A SIMPLE PROGRAM WITH INHERITANCE
  33. -----------------------------------------------------------------
  34. Examine the example program named              ==================
  35. VIRTUAL1.CPP for the basic program outline        VIRTUAL1.CPP
  36. we will use for all discussion in this         ==================
  37. chapter.  Since this program has nothing to 
  38. do with virtual functions, the name may be somewhat misleading.  
  39. It is named VIRTUAL1.CPP because it is part of a series of 
  40. programs intended to illustrate the use of virtual functions. The 
  41. last program in this chapter will illustrate the proper use of 
  42. virtual functions.  The first program is very simple and you will 
  43. recognize it as being similar to the programs studied in the last 
  44. chapter except that this program is greatly simplified in order 
  45. to effectively instruct you in the use of a virtual function.  
  46. You will notice that many of the methods from the last chapter 
  47. have been completely dropped from this example for simplicity, 
  48. and a new method has been added to the parent class, the method 
  49. named message() in line 8.  Throughout this chapter we will be 
  50. studying the operation of the method named message() in the base 
  51. class and the derived classes.  For that reason, there is a 
  52. method named message() in the car class as well as in the new 
  53. class named boat in lines 27 through 32.
  54.  
  55.  
  56.  
  57.                                                         Page 10-1
  58.  
  59.                                    Chapter 10 - Virtual Functions
  60.  
  61. You will also notice that there is a lack of a method named 
  62. message() in the truck class.  This has been done on purpose to 
  63. illustrate the use of the virtual method, or if you prefer, you 
  64. can refer to it as a virtual function.  You will recall that the 
  65. method named message() from the base class is available in the 
  66. truck class because the method from the base class is inherited 
  67. with the keyword public included in line 19.  You will also 
  68. notice that the use of the keyword public in lines 12 and 27 
  69. actually do nothing because the only method available in the base 
  70. class is also available in the derived classes.  There are no 
  71. methods actually inherited.  Leaving the keyword in the header 
  72. poses no problem however, so it will be left there for your 
  73. study.
  74.  
  75. The method named message() in the base class and in the derived 
  76. classes has been kept very simple on purpose.  Once again, we are 
  77. interested in the technique of the virtual method rather than a 
  78. long complicated example.
  79.  
  80. The main program is as simple as the classes, one object of each 
  81. of the classes is declared in lines 37 through 40 and the method 
  82. named message() is called once for each object.  The result of 
  83. executing the program indicates that the method for each is 
  84. called except for the object named semi, which has no method 
  85. named message().  As discussed in the last chapter, the method 
  86. named message() from the parent class is called and the data 
  87. output to the monitor indicates that this did happen since it 
  88. displays "Vehicle message" for the object named semi.
  89.  
  90. The data for the objects is of no concern in this chapter so all 
  91. data is allowed to default to private type and none is inherited 
  92. into the derived classes.  Some of the data is left in the 
  93. example program simply to make the classes look like classes.  
  94. Based on your experience with C++ by now, you realize that the 
  95. data could be removed since it is not used.
  96.  
  97. After you understand this program, compile and execute it to see 
  98. if your compiler gives the same result of execution.
  99.  
  100.  
  101. ADDING THE KEYWORD VIRTUAL
  102. -----------------------------------------------------------------
  103. As you examine the next example program        ==================
  104. named VIRTUAL2.CPP, you will notice that          VIRTUAL2.CPP
  105. there is one small change in line 8.  The      ==================
  106. keyword virtual has been added to the 
  107. declaration of the method named message() in the parent class.  
  108. It may be a bit of a disappointment to you to learn that this 
  109. program operates no differently than the last example program.  
  110. This is because we are using objects directly and virtual methods 
  111. have nothing to do with objects, only with pointers to objects as 
  112. we will see soon.  There is an additional comment in line 46 
  113. illustrating that since all four objects are of different 
  114.  
  115.                                                         Page 10-2
  116.  
  117.                                    Chapter 10 - Virtual Functions
  118.  
  119. classes, it is impossible to assign any object to any other 
  120. object in this program.  We will soon see that some pointer 
  121. assignments are permitted between objects of dissimilar classes.
  122.  
  123. After you are sure that the fact that they are virtual functions, 
  124. or methods, has nothing to do with the objects as they are 
  125. instantiated, compile and execute this example program to see if 
  126. your compiler results in the same output as that listed.
  127.  
  128.  
  129. USING OBJECT POINTERS
  130. -----------------------------------------------------------------
  131. Examine the example program named              ==================
  132. VIRTUAL3.CPP and you will find a repeat of        VIRTUAL3.CPP
  133. the first program but with a different main    ==================
  134. program. In this program the keyword virtual 
  135. has been removed from the method declaration in the parent class 
  136. in line 8, and the main program declares pointers to the objects 
  137. rather than declaring the objects themselves in lines 37 through 
  138. 40.  Since we only declared pointers to the objects we find it 
  139. necessary to allocate the objects before using them by using the 
  140. new operator in lines 42 through 49.  Upon running the program, 
  141. we find that even though we are using pointers to the objects we 
  142. have done nothing different than what we did in the first 
  143. program.  Upon execution, we find that the program operates in 
  144. exactly the same manner as the first example program in this 
  145. chapter.  This should not be surprising because a pointer to a 
  146. method can be used to operate on an object in the same manner as 
  147. an object can be manipulated.
  148.  
  149. Be sure to compile and execute this program before continuing on 
  150. to the next example program.  The observant student will notice 
  151. that we failed to deallocate the objects prior to terminating the 
  152. program.  As always, in such a simple program, it doesn't matter 
  153. because the heap will be cleaned up automatically when we return 
  154. to the operating system.
  155.  
  156.  
  157. A POINTER AND A VIRTUAL FUNCTION
  158. -----------------------------------------------------------------
  159. The example program named VIRTUAL4.CPP is      ==================
  160. identical to the last program except for the      VIRTUAL4.CPP
  161. addition of the keyword virtual to line 8      ==================
  162. once again.  I hope you are not terribly 
  163. disappointed to find that this program, including the keyword 
  164. virtual, is still identical to the last program.  Once again we 
  165. are simply using pointers to each of the objects, and in every 
  166. case the pointer is of the same type as the object to which it 
  167. points.  You will begin to see some changes in the next example 
  168. program, so be patient, we are almost there.
  169.  
  170. Once again, it would be best for you to compile and execute this 
  171. program.
  172.  
  173.                                                         Page 10-3
  174.  
  175.                                    Chapter 10 - Virtual Functions
  176.  
  177. The four previous programs were meant to instruct you in what 
  178. virtual functions do not do.  The next two will show you what 
  179. virtual functions do.
  180.  
  181.  
  182. A SINGLE POINTER TO THE PARENT CLASS
  183. -----------------------------------------------------------------
  184. Examine the example program named              ==================
  185. VIRTUAL5.CPP where we almost use a virtual        VIRTUAL5.CPP
  186. method.  Be just a little patient because we   ==================
  187. are almost ready to actually use a virtual 
  188. method.
  189.  
  190. You will notice that this is another copy of our program with the 
  191. keyword virtual omitted from line 8 and with a totally different 
  192. main program.  In this program, we only declare a single pointer 
  193. to a class and the pointer is pointing to the base class of the 
  194. class hierarchy.  We will use the single pointer to refer to each 
  195. of the four classes and observe what the output of the method 
  196. named message() is.
  197.  
  198. A little digression is in order to understand how we can use a 
  199. pointer which has been declared to point to one class, to 
  200. actually refer to another class.  If we referred to a vehicle (in 
  201. the real world, not necessarily in this program), we could be 
  202. referring to a car, a truck, a motorcycle, or any other kinds of 
  203. transportation, because we are referring to a very general form 
  204. of an object.  If however, we were to refer to a car, we are 
  205. excluding trucks, motorcycles, and all other kinds of 
  206. transportation, because we are referring to a car specifically.  
  207. The more general term of vehicle can therefore refer to many 
  208. kinds of vehicles, but the more specific term of car can only 
  209. refer to a single kind of vehicle, namely a car.
  210.  
  211. We can apply the same thought process in C++ and say that if we 
  212. have a pointer to a vehicle (remembering that a pointer is 
  213. actually a reference), we can use that pointer to refer to any of 
  214. the more specific objects, and that is indeed legal in C++ 
  215. according to the definition of the language.  In a like manner, 
  216. if we have a pointer to a car, we cannot use that pointer to 
  217. reference any of the other classes including the vehicle class 
  218. because the pointer to the car class is too specific and 
  219. restricted to be used on any of the other classes.
  220.  
  221.  
  222. THE C++ POINTER RULE
  223. -----------------------------------------------------------------
  224. The rule as given in C++ terms is as follows.  A pointer declared 
  225. as pointing to a base class can be used to point to an object of 
  226. a derived class of that base class, but a pointer to a derived 
  227. class cannot be used to point to an object of the base class or 
  228. to any of the other derived classes of the base class.  In our 
  229. program therefore, we are allowed to declare a pointer to the 
  230.  
  231.                                                         Page 10-4
  232.  
  233.                                    Chapter 10 - Virtual Functions
  234.  
  235. vehicle class which is the base class, and use that pointer to 
  236. refer to objects of the base class or any of the derived classes.
  237.  
  238. This is exactly what we do in the main program.  We declare a 
  239. single pointer which points to the vehicle class and use it to 
  240. point to objects of each of the classes in the same order as in 
  241. the last four programs.  In each case, we allocate the object, 
  242. send a message to the method named message() and deallocate the 
  243. object before going on to the next class.  You will notice that 
  244. when we send the four messages, we are sending the message to the 
  245. same method, namely the method named message() which is a part of 
  246. the vehicle base class.  This is because the pointer has a class 
  247. associated with it.  Even though the pointer is actually pointing 
  248. to four different classes in this program, the program acts as if 
  249. the pointer is always pointing to an object of the parent class 
  250. because the pointer is of the type of the parent class.
  251.  
  252. The next program will finally do something you have not seen in 
  253. any C program or in any C++ program in this tutorial up to this 
  254. point.  After you compile and execute the current program, we 
  255. will go on to study our first virtual function.
  256.  
  257.  
  258. AN ACTUAL VIRTUAL FUNCTION
  259. -----------------------------------------------------------------
  260. We finally come to an example program with a   ==================
  261. virtual function that operates as a virtual       VIRTUAL6.CPP
  262. function and exhibits dynamic binding or       ==================
  263. polymorphism as it is called.  This is in the 
  264. program named VIRTUAL6.CPP. This program is identical to the last 
  265. example program except that the keyword virtual is added to line 
  266. 8 to make the method named message() a virtual function.  You 
  267. will notice that the keyword virtual only appears in the base 
  268. class, all classes that derive this class will have the 
  269. corresponding method automatically declared virtual by the 
  270. system.  In this program, we will once again use the single 
  271. pointer to the base class and allocate, use, then delete an 
  272. object of each of the four available classes using the identical 
  273. code we used in the last program.  However, because of the 
  274. addition of the keyword virtual in line 8, this program acts 
  275. entirely different from the last example program.
  276.  
  277. Since the method named message() is declared to be a virtual 
  278. method in its declaration in the base class, anytime we refer to 
  279. this method with a pointer to the base class, we actually execute 
  280. the method associated with one of the derived classes if there is 
  281. a method available in the derived class and if the pointer is 
  282. actually pointing to that derived class.  When the program is 
  283. executed, the output reflects the same output we saw in the other 
  284. cases when we were actually calling the methods in the derived 
  285. classes, but now we are using a pointer of the base class type to 
  286. make the calls.
  287.  
  288.  
  289.                                                         Page 10-5
  290.  
  291.                                    Chapter 10 - Virtual Functions
  292.  
  293. You will notice that in lines 40, 44, 48, and 52, even though the 
  294. code is identical in each line, the system is making the decision 
  295. of which method to actually call based on the type of the pointer 
  296. when each message is sent.  The decision of which method to call 
  297. is not made during the time when the code is compiled but when 
  298. the code is executed.  This is dynamic binding and can be very 
  299. useful in some programming situations.  In fact, there are only 
  300. three different calls made because the class named truck does not 
  301. have a method named message(), so the system simply uses the 
  302. method from the base class to satisfy the message passed.  For 
  303. this reason, a virtual function must have an implementation 
  304. available in the base class which will be used if one is not 
  305. available in one or more of the derived classes.  Note that the 
  306. message is actually sent to a pointer to the object, but this is 
  307. splitting hairs and should not be overly emphasized at this time.
  308.  
  309. It is probably not obvious, but the observant student will note 
  310. that the structure of the virtual function in the base class and 
  311. each of the derived classes is identical.  The return type and 
  312. the number and types of the parameters must be identical for all 
  313. functions, since a single statement can be used to call any of 
  314. them.
  315.  
  316.  
  317. IS THIS REALLY SIGNIFICANT?
  318. -----------------------------------------------------------------
  319. This program probably does not seem to do much when you first 
  320. approach it, but the dynamic binding is a very useful construct 
  321. and will be illustrated in the next chapter with a rather simple 
  322. program that uses the technique of dynamic binding to implement a 
  323. personnel list for a small company.  If the keyword virtual is 
  324. used, the system will use late binding which is done at run time, 
  325. but if the keyword is not included, early binding will be used.  
  326. What these words actually mean is that with late binding, the 
  327. compiler does not know which method will actually respond to the 
  328. message because the type of the pointer is not known at compile 
  329. time.  With early binding, however, the compiler decides at 
  330. compile time what method will respond to the message sent to the 
  331. pointer.
  332.  
  333. Be sure to compile and execute this example program before 
  334. continuing on to the next chapter where we will see a practical 
  335. example of the use of this technique.
  336.  
  337.  
  338. PROGRAMMING EXERCISES
  339. -----------------------------------------------------------------
  340. 1.  Modify VIRTUAL3.CPP to deallocate the objects prior to 
  341.     terminating the program.
  342.  
  343. 2.  Add a message() method to the truck class of VIRTUAL6.CPP to 
  344.     observe the use of the new method instead of defaulting to 
  345.     the parent class method.
  346.  
  347.                                                         Page 10-6
  348.