home *** CD-ROM | disk | FTP | other *** search
/ Shareware 1 2 the Maxx / sw_1.zip / sw_1 / PROGRAM / CPTUTT22.ZIP / CHAP06.TXT < prev    next >
Text File  |  1992-01-20  |  37KB  |  767 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.                                                         Chapter 6
  8.                                                MORE ENCAPSULATION
  9.  
  10.  
  11. The purpose of this chapter is to illustrate how to use some of the
  12. traditional aspects of C or C++ with classes and objects.  Pointers
  13. to an object as well as pointers within an object will be
  14. illustrated.  Arrays embedded within an object, and an array of
  15. objects will be illustrated.  Since objects are simply another C++
  16. data construct, all of these things are possible and can be used
  17. if needed.
  18.  
  19. In order to have a systematic study, we will use the program named
  20. BOXES1.CPP from the last chapter as a starting point and we will
  21. add a few new constructs to it for each example program.  You will
  22. recall that it was a very simple program with the class definition,
  23. the class implementation, and the main calling program all in one
  24. file.  This was selected as a starting point because we will
  25. eventually make changes to all parts of the program and it will be
  26. convenient to have it all in a single file for illustrative
  27. purposes.  It must be kept in mind however that the proper way to
  28. use these constructs is to separate them into the three files as
  29. was illustrated in BOX.H, BOX.CPP, and BOXES2.CPP in the last
  30. chapter.  This allows the implementor of box to supply the user
  31. with only the interface, namely  BOX.H.  Not giving him the
  32. implementation file named BOX.CPP, is practicing the technique of
  33. information hiding.
  34.  
  35. As we have said many times, it seems silly to break up such a small
  36. program into three separate files, and it is sort of silly.  The
  37. last chapter of this tutorial will illustrate a program large
  38. enough to require dividing the program up into many separate files.
  39.  
  40.  
  41. AN ARRAY OF OBJECTS
  42. _________________________________________________________________
  43.  
  44. Examine the file named OBJARRAY.CPP for our      ================
  45. first example of an array of objects.  This file   OBJARRAY.CPP
  46. is nearly identical to the file named BOX1.CPP   ================
  47. until we come to line 44 where an array of 4
  48. boxes are declared.
  49.  
  50. Recalling the operation of the constructor you will remember that
  51. each of the four box objects will be initialized to the values
  52. defined within the constructor since each box will go through the
  53. constructor as they are declared.  In order to declare an array of
  54. objects, a constructor for that object must not require any
  55. parameters.  (We have not yet illustrated a constructor with
  56. initializing parameters, but we will in the next program.)  This
  57.  
  58.                                                          Page 6-1
  59.  
  60.                                    Chapter 6 - More Encapsulation
  61.  
  62. is an efficiency consideration since it would probably be an error
  63. to initialize all elements of an array of objects to the same
  64. value.  We will see the results of executing the constructor when
  65. we compile and execute the file later.
  66.  
  67. Line 49 defines a for loop that begins with 1 instead of the normal
  68. starting index for an array leaving the first object, named
  69. group[0], to use the default values stored when the constructor was
  70. called.  You will observe that sending a message to one of the
  71. objects uses the same construct as is used for any object.  The
  72. name of the array followed by its index in square brackets is used
  73. to send a message to one of the objects in the array.  This is
  74. illustrated in line 50 and the operation of that code should be
  75. clear to you.  The other method is called in the output statement
  76. in lines 57 and 58 where the area of the four boxes in the group
  77. array are listed on the monitor.
  78.  
  79. Another fine point should be pointed out.  The integer variable
  80. named index is declared in line 49 and is still available for use
  81. in line 56 since we have not yet left the enclosing block which
  82. begins in line 43 and extends to line 65.
  83.  
  84.  
  85.  
  86. DECLARATION AND DEFINITION OF A VARIABLE
  87. _________________________________________________________________
  88.  
  89. An extra variable was included for illustration, the one named
  90. extra_data in line seven.  Since the keyword static is used to
  91. modify this variable in line 7, it is an external variable and only
  92. one copy of this variable will ever exist.  All seven objects of
  93. this class share a single copy of this variable which is global to
  94. the objects defined in line 44.
  95.  
  96. The variable is actually only declared here which says it will
  97. exist somewhere, but it is not defined.  A declaration says the
  98. variable will exist and gives it a name, but the definition
  99. actually defines a place to store it somewhere in the computers
  100. memory space.  By definition, a static variable can be declared in
  101. a class header but it cannot be defined there, so it is defined
  102. somewhere outside of the header, usually in the implementation
  103. file.  In this case it is defined in line 16 and can then be used
  104. throughout the class.
  105.  
  106. Line 23 of the constructor sets the single global variable to 1
  107. each time an object is declared.  Only one assignment is necessary
  108. so the other six are actually wasted code.  To illustrate that
  109. there is only one variable shared by all objects of this class,
  110. the method to read its value also increments it.  Each time it is
  111. read in lines 60 through 64, it is incremented and the result of
  112. the execution proves that there is only a single variable shared
  113. by all objects of this class.  You will also note that the method
  114. named get_extra() is defined within the class declaration so it
  115. will be assembled into the final program as inline code.
  116.  
  117.                                                          Page 6-2
  118.  
  119.                                    Chapter 6 - More Encapsulation
  120.  
  121.  
  122. Be sure you understand this program and especially the static
  123. variable, then compile and execute it to see if you get the same
  124. result as listed at the end of the program.
  125.  
  126.  
  127. A STRING WITHIN AN OBJECT
  128. _________________________________________________________________
  129.  
  130. Examine the program named OBJSTRNG.CPP for our   ================
  131. first example of an object with an embedded        OBJSTRNG.CPP
  132. string.  Actually, the object does not have an   ================
  133. embedded string, it has an embedded pointer, but
  134. the two work so closely together that we can
  135. study one and understand both.
  136.  
  137. You will notice that line 7 contains a pointer to a string named
  138. line_of_text.  The constructor contains an input parameter which
  139. is a pointer to a string which will be copied to the string named
  140. line_of_text within the constructor.  We could have defined the
  141. variable line_of_text as an actual array in the class, then used
  142. strcpy() to copy the string into the object and everything would
  143. have worked the same, but we will leave that as an exercise for you
  144. at the end of this chapter.  It should be pointed out that we are
  145. not limited to passing a single parameter to a constructor.  Any
  146. number of parameters can be passed, as will be illustrated later.
  147.  
  148. You will notice that when the three boxes are declared this time,
  149. we supply a string constant as an actual parameter with each
  150. declaration which is used by the constructor to assign the string
  151. pointer some data to point to.  When we call get_area() in lines
  152. 48 through 53, we get the message displayed and the area returned.
  153. It would be prudent to put these operations in separate methods
  154. since there is no apparent connection between printing the message
  155. and calculating the area, but it was written this way to illustrate
  156. that it can be done.  What this really says is that it is possible
  157. to have a method that has a side effect, the message output to the
  158. monitor, and a return value, the area of the box.  However, as we
  159. discussed in chapter 4 when we studied DEFAULT.CPP, the order of
  160. evaluation is sort of funny, so we broke each line into two lines.
  161.  
  162. After you understand this program, compile and execute it.
  163.  
  164.  
  165. AN OBJECT WITH AN INTERNAL POINTER
  166. _________________________________________________________________
  167.  
  168. The program named OBJINTPT.CPP is our first      ================
  169. example program with an embedded pointer which     OBJINTPT.CPP
  170. will be used for dynamic allocation of data.     ================
  171.  
  172. In line 7 we declare a pointer to an integer
  173. variable, but it is only a pointer, there is no storage associated
  174. with it.  The constructor therefore allocates an integer type
  175.  
  176.                                                          Page 6-3
  177.  
  178.                                    Chapter 6 - More Encapsulation
  179.  
  180. variable on the heap for use with this pointer in line 21.  It
  181. should be clear to you that the three objects created in line 45
  182. each contain a pointer which points into the heap to three
  183. different locations.  Each object has its own dynamically allocated
  184. variable for its own private use.  Moreover each has a value of 112
  185. stored in its dynamically allocated data because line 22 stores
  186. that value in each of the three locations, once for each call to
  187. the constructor.
  188.  
  189. In such a small program, there is no chance that we will exhaust
  190. the heap, so no test is made for unavailable memory.  In a real
  191. production program, it would be expedient to test that the value
  192. of the returned pointer is not NULL to assure that the data
  193. actually did get allocated.
  194.  
  195. The method named set() has three parameters associated with it and
  196. the third parameter is used to set the value of the new dynamically
  197. allocated variable.  There are two messages passed, one to the
  198. small box and one to the large box.  As before, the medium box is
  199. left with its default values.
  200.  
  201. The three areas are displayed followed by the three stored values
  202. in the dynamically allocated variables, and we finally have a
  203. program that requires a destructor in order to be completely
  204. proper.  If we simply leave the scope of the objects as we do when
  205. we leave the main program, we will leave the three dynamically
  206. allocated variables on the heap with nothing pointing to them.
  207. They will be inaccessible and will therefore represent wasted
  208. storage on the heap.  For that reason, the destructor is used to
  209. delete the variable which the pointer named point is referencing
  210. as each object goes out of existence.  In this case, lines 37 and
  211. 38 assign values to variables that will be automatically deleted.
  212. Even though these lines of code really do no good, they are legal
  213. statements.
  214.  
  215. Actually, in this particular case, the variables will be
  216. automatically reclaimed when we return to the operating system
  217. because all program cleanup is done for us at that time.  If this
  218. were a function that was called by another function however, the
  219. heap space would be wasted.  This is an illustration of good
  220. programming practice, that of cleaning up after yourself when you
  221. no longer need some dynamically allocated variables.
  222.  
  223. One other construct should be mentioned once again, that of the
  224. inline method implementations in line 11 and 12.  As we mentioned
  225. in chapter 5 and repeated earlier in this chapter, inline functions
  226. can be used where speed is of the utmost in importance since the
  227. code is assembled inline rather than by actually making a method
  228. call.  Since the code is defined as part of the declaration, the
  229. system will assemble it inline, and a separate implementation for
  230. these methods is not needed.  If the inline code is too involved,
  231. the compiler is allowed to ignore the inline request and will
  232. actually assemble it as a separate method, but it will do it
  233. invisibly to you and will probably not even tell you about it.
  234.  
  235.                                                          Page 6-4
  236.  
  237.                                    Chapter 6 - More Encapsulation
  238.  
  239.  
  240. Remember that we are interested in using information hiding and
  241. inline code prevents hiding of the implementation, putting it out
  242. in full view.  Many times you will be more interested in speeding
  243. up a program than you are in hiding a trivial implementation.
  244. Since most inline methods are trivial, feel free to use the inline
  245. code construct.
  246.  
  247. Be sure to compile and execute this program.
  248.  
  249.  
  250. A DYNAMICALLY ALLOCATED OBJECT
  251. _________________________________________________________________
  252.  
  253. Examine the file named OBJDYNAM.CPP for our      ================
  254. first look at a dynamically allocated object.      OBJDYNAM.CPP
  255. This is not any different than any other         ================
  256. dynamically allocated object, but an example is
  257. always helpful.
  258.  
  259. In line 39 we declare a pointer to an object of type box and since
  260. it is only a pointer with nothing to point to, we dynamically
  261. allocate an object for it in line 44, with the object being created
  262. on the heap just like any other dynamically allocated variable.
  263. When the object is created in line 44, the constructor is called
  264. automatically to assign values to the two internal storage
  265. variables.  Note that the constructor is not called when the
  266. pointer is declared since there is nothing to initialize.  It is
  267. called when the object is allocated.
  268.  
  269. Reference to the components of the object are handled in much the
  270. same way that structure references are made, through use of the
  271. pointer operator as illustrated in lines 50 through 52.  Of course
  272. you can use the pointer dereferencing method without the arrow such
  273. as (*point).set(12, 12); as a replacement for line 51 but the arrow
  274. notation is much more universal and should be used.  Finally, the
  275. object is deleted in line 54 and the program terminates.  If there
  276. were a destructor for this class, it would be called as part of the
  277. delete statement to clean up the object prior to deletion.
  278.  
  279. You have probably noticed by this time that the use of objects is
  280. not much different from the use of structures.  Be sure to compile
  281. and execute this program after you have studied it thoroughly.
  282.  
  283.  
  284.  
  285. AN OBJECT WITH A POINTER TO ANOTHER OBJECT
  286. _________________________________________________________________
  287.  
  288. The program named OBJLIST.CPP contains an object  ===============
  289. with an internal reference to another object of     OBJLIST.CPP
  290. its own class.  This is the standard structure    ===============
  291. used for a singly linked list and we will keep
  292. the use of it very simple in this program.
  293.  
  294.                                                          Page 6-5
  295.  
  296.                                    Chapter 6 - More Encapsulation
  297.  
  298.  
  299. The constructor contains the statement in line 21 which assigns the
  300. pointer the value of NULL to initialize the pointer.  This is a
  301. good idea for all of your programming, don't allow any pointer to
  302. point off into space, but initialize all pointers to something.
  303. By assigning the pointer within the constructor, you guarantee that
  304. every object of this class will automatically have its pointer
  305. initialized.  It will be impossible to overlook the assignment of
  306. one of these pointers.
  307.  
  308. Two additional methods are declared in lines 12 and 13 with the one
  309. in line 13 having a construct we have not yet mentioned in this
  310. tutorial.  This method returns a pointer to an object of the box
  311. class.  As you are aware, you can return a pointer to a struct in
  312. standard C, and this is a parallel construct in C++.  The
  313. implementation in lines 48 through 51 returns the pointer stored
  314. within the object.  We will see how this is used when we get to the
  315. actual program.
  316.  
  317. An extra pointer named box_pointer is declared in the main program
  318. for use later and in line 66 we make the embedded pointer within
  319. the small box point to the medium box, and in line 67 we make the
  320. embedded pointer within the medium box point to the large box.  We
  321. have effectively generated a linked list with three elements.  In
  322. line 69 we make the extra pointer point to the small box.
  323. Continuing in line 70 we use it to refer to the small box and
  324. update it to the value contained in the small box which is the
  325. address of the medium box.  We have therefore traversed from one
  326. element of the list to another by sending a message to one of the
  327. objects.  If line 70 were repeated exactly as shown, it would cause
  328. the extra pointer to refer to the large box, and we would have
  329. traversed the entire linked list which is only composed of three
  330. elements.
  331.  
  332.  
  333.  
  334. ANOTHER NEW KEYWORD this
  335. _________________________________________________________________
  336.  
  337. Another new keyword is available in C++, the keyword this.  The
  338. word this is defined within any object as being a pointer to the
  339. object in which it is contained.  It is implicitly declared as;
  340.  
  341.    class_name *this;
  342.  
  343. and is initialized to point to the object for which the member
  344. function is invoked.  This pointer is most useful when working with
  345. pointers and especially with a linked list when you need to
  346. reference a pointer to the object you are inserting into the list.
  347. The keyword this is available for this purpose and can be used in
  348. any object.  Actually the proper way to refer to any variable
  349. within a list is through use of the predefined pointer this, by
  350. writing this->variable_name, but the compiler assumes the pointer
  351. is used, and we can simplify every reference by omitting the
  352.  
  353.                                                          Page 6-6
  354.  
  355.                                    Chapter 6 - More Encapsulation
  356.  
  357. pointer.  Use of the keyword this is not illustrated in a program
  358. at this point, but will be used in one of the larger example
  359. programs later in this tutorial.
  360.  
  361. You should study this program until you understand it completely
  362. then compile and execute it in preparation for our next example
  363. program.
  364.  
  365.  
  366.  
  367. A LINKED LIST OF OBJECTS
  368. _________________________________________________________________
  369.  
  370. The next example program in this chapter is       ===============
  371. named OBJLINK.CPP and is a complete example of      OBJLINK.CPP
  372. a linked list written in object oriented          ===============
  373. notation.
  374.  
  375. This program is very similar to the last one.  In fact it is
  376. identical until we get to the main program.  You will recall that
  377. in the last program the only way we had to set or use the embedded
  378. pointer was through use of the two methods named point_at_next()
  379. and get_next() which are listed in lines 40 through 51 of the
  380. present program.  We will use these to build up our linked list
  381. then traverse and print the list.  Finally, we will delete the
  382. entire list to free the space on the heap.
  383.  
  384. In lines 56 to 58 we declare three pointers for use in the program.
  385. The pointer named start will always point to the beginning of the
  386. list, but temp will move down through the list as we create it.
  387. The pointer named box_pointer will be used for the creation of each
  388. object.  We execute the loop in lines 61 through 69 to generate
  389. the list where line 62 dynamically allocates a new object of the
  390. box class and line 63 fills it with nonsense data for illustration.
  391. If this is the first element in the list, the start pointer is set
  392. to point to this element, but if elements already exist, the last
  393. element in the list is assigned to point to the new element.  In
  394. either case, the temp pointer is assigned to point to the last
  395. element of the list, in preparation for adding another element if
  396. there is another element to be added.
  397.  
  398. In line 72, the pointer named temp is pointed to the first element
  399. and it is used to increment its way through the list by updating
  400. itself in line 75 during each pass through the loop.  When temp has
  401. the value of NULL, which it gets from the last element of the list,
  402. we are finished traversing the list.
  403.  
  404. Finally, we delete the entire list by starting at the beginning and
  405. deleting one element each time we pass through the loop in lines
  406. 79 through 84.
  407.  
  408. A careful study of the program will reveal that it does indeed
  409. generate a linked list of ten elements, each element being an
  410. object of class box.  The length of this list is limited by the
  411.  
  412.                                                          Page 6-7
  413.  
  414.                                    Chapter 6 - More Encapsulation
  415.  
  416. practicality of how large a list we desire to print out, but it
  417. could be lengthened to many thousands of these simple elements
  418. provided you have enough memory available to store them all.
  419.  
  420. Once again, the success of the dynamic allocation is not checked
  421. as it should be in a correctly written program.  Be sure to compile
  422. and execute this example program.
  423.  
  424.  
  425.  
  426. NESTING OBJECTS
  427. _________________________________________________________________
  428.  
  429. Examine the program named NESTING.CPP for an    =================
  430. example of nesting classes which results in        NESTING.CPP
  431. nested objects.  A nested object could be       =================
  432. illustrated with your computer in a rather
  433. simple manner.  The computer itself is composed
  434. of many items which work together but work entirely differently,
  435. such as a keyboard, a disk drive, and a power supply.  The computer
  436. is composed of these very dissimilar items and it is desireable to
  437. discuss the keyboard separately from the disk drive because they
  438. are so different.  A computer class could be composed of several
  439. objects that are dissimilar by nesting the dissimilar classes
  440. within the computer class.
  441.  
  442. If however, we wished to discuss disk drives, we may wish to
  443. examine the characteristics of disk drives in general, then examine
  444. the details of a hard disk, and the differences of floppy disks.
  445. This would involve inheritance because much of the data about both
  446. drives could be characterized and applied to the generic disk drive
  447. then used to aid in the discussion of the other three.  We will
  448. study inheritance in the next three chapters, but for now we will
  449. look at the embedded or nested class.
  450.  
  451. This example program contains a class named box which contains an
  452. object of another class embedded within it in line 16, the
  453. mail_info class.  This object is available for use only within the
  454. class implementation of box because that is where it is defined.
  455. The main program has objects of class box defined but no objects
  456. of class mail_info, so the mail_info class cannot be referred to
  457. in the main program.  In this case, the mail_info class object is
  458. meant to be used internally to the box class and one example is
  459. given in line 21 where a message is sent to the label.set() method
  460. to initialize the variables.  Additional methods could be used as
  461. needed, but these are given as an illustration of how they can be
  462. called.
  463.  
  464. Of prime importance is the fact that there are never any objects
  465. of the mail_info class declared directly in the main program, they
  466. are inherently declared when the enclosing objects of class box are
  467. declared.  Of course objects of the mail_info class could be
  468. declared and used in the main program if needed, but they are not
  469. in this example program.  In order to be complete, the box class
  470.  
  471.                                                          Page 6-8
  472.  
  473.                                    Chapter 6 - More Encapsulation
  474.  
  475. should have one or more methods to use the information stored in
  476. the object of the mail_info class.  Study this program until you
  477. understand the new construct, then compile and execute it.
  478.  
  479. If the class and the nested classes require parameter lists for
  480. their respective constructors an initialization list can be given.
  481. This will be discussed and illustrated later in this tutorial.
  482.  
  483.  
  484. OPERATOR OVERLOADING
  485. _________________________________________________________________
  486.  
  487. The example file named OPOVERLD.CPP contains     ================
  488. examples of overloading operators.  This allows    OPOVERLD.CPP
  489. you to define a class of objects and redefine    ================
  490. the use of the normal operators.  The end result
  491. is that objects of the new class can be used in
  492. as natural a manner as the predefined types.  In fact, they seem
  493. to be a part of the language rather than your own add-on.
  494.  
  495. In this case we overload the + operator and the * operator, with
  496. the declarations in lines 10 through 12, and the definitions in
  497. lines 16 through 40.  The methods are declared as friend functions
  498. so we can use the double parameter functions as listed.  If we did
  499. not use the friend construct, the function would be a part of one
  500. of the objects and that object would be the object to which the
  501. message was sent.  Including the friend construct allows us to
  502. separate this method from the object and call the method with infix
  503. notation.  Using this technique, it can be written as object1 +
  504. object2 rather than object1.operator+(object2).  Also, without the
  505. friend construct we could not use an overloading with an int type
  506. variable for the first parameter because we can not send a message
  507. to an integer type variable such as int.operator+(object).  Two of
  508. the three operator overloadings use an int for the first parameter
  509. so it is necessary to declare them as friend functions.
  510.  
  511.  
  512. There is no upper limit to the number of overloadings for any given
  513. operator.  Any number of overloadings can be used provided the
  514. parameters are different for each particular overloading.
  515.  
  516. The header in line 16 illustrates the first overloading where the
  517. + operator is overloaded by giving the return type followed by the
  518. keyword operator and the operator we wish to overload.  The two
  519. formal parameters and their types are then listed in the
  520. parentheses and the normal function operations are given in the
  521. implementation of the function in lines 18 through 21.  The
  522. observant student will notice that the implementation of the friend
  523. functions are not actually a part of the class because the class
  524. name is not prepended onto the method name in line 16.  There is
  525. nothing unusual about this implementation, it should be easily
  526. understood by you at this point.  For purposes of illustration,
  527. some silly mathematics are performed in the method implementation,
  528. but any desired operations can be done.
  529.  
  530.                                                          Page 6-9
  531.  
  532.                                    Chapter 6 - More Encapsulation
  533.  
  534.  
  535. The biggest difference occurs in line 56 where this method is
  536. called by using the infix notation instead of the usual message
  537. sending format.  Since the variables small and medium are objects
  538. of the box class, the system will search for a way to use the +
  539. operator on two objects of class box and will find it in the
  540. overloaded operator+ method we have just discussed.  The operations
  541. within the method implementation can be anything we need them to
  542. be, and they are usually much more meaningful than the silly math
  543. included here.
  544.  
  545. In line 58 we ask the system to add an int type constant to an
  546. object of class box, so the system finds the other overloading of
  547. the + operator beginning in line 25 to perform this operation.
  548. Also in line 60 we ask the system to use the * operator to do
  549. something to an int constant and an object of class box, which it
  550. satisfies by finding the method in lines 34 through 40.  Note that
  551. it would be illegal to attempt to use the * operator the other way
  552. around, namely large * 4 since we did not define a method to use
  553. the two types in that order.  Another overloading could be given
  554. with reversed types, and we could use the reverse order in a
  555. program.
  556.  
  557. You will notice that when using operator overloading, we are also
  558. using function name overloading since some of the function names
  559. are the same.
  560.  
  561. When we use operator overloading in this manner, we actually make
  562. our programs look like the class is a natural part of the language
  563. since it is integrated into the language so well.  C++ is therefore
  564. an extendible language and can be molded to fit the mechanics of
  565. the problem at hand.
  566.  
  567.  
  568.  
  569. OPERATOR OVERLOADING CAVEATS
  570. _________________________________________________________________
  571.  
  572. Each new topic we study has its pitfalls which must be warned
  573. against and the topic of operator overloading seems to have the
  574. record for pitfalls since it is so prone to misuse and has several
  575. problems.  The overloading of operators is only available for
  576. classes, you cannot redefine the operators for the predefined
  577. simple types.  This would probably be very silly anyway since the
  578. code could be very difficult to read if you changed some of them
  579. around.
  580.  
  581. The logical and (&&) and the logical or (||) operators can be
  582. overloaded for the classes you define, but they will not operate
  583. as short circuit operators.  All members of the logical
  584. construction will be evaluated with no regard concerning the
  585. outcome.  Of course the normal predefined logical operators will
  586. continue to operate as short circuit operators as expected, but not
  587. the overloaded ones.
  588.  
  589.                                                         Page 6-10
  590.  
  591.                                    Chapter 6 - More Encapsulation
  592.  
  593.  
  594. If the increment (++) or decrement (--) operators are overloaded,
  595. the system has no way of telling whether the operators are used as
  596. preincrement or postincrement (or predecrement or postdecrement)
  597. operators.  Which method is used is implementation dependent, so
  598. you should use them in such a way that it doesn't matter which is
  599. used.
  600.  
  601. Be sure to compile and execute OPOVERLD.CPP before continuing on
  602. to the next example program.
  603.  
  604.  
  605.  
  606. FUNCTION OVERLOADING IN A CLASS
  607. _________________________________________________________________
  608.  
  609. Examine the program named FUNCOVER.CPP for an    ================
  610. example of function name overloading within a      FUNCOVER.CPP
  611. class.  In this program the constructor is       ================
  612. overloaded as well as one of the methods to
  613. illustrate what can be done.
  614.  
  615. This file illustrates some of the uses of overloaded names and a
  616. few of the rules for their use.  You will recall that the function
  617. selected is based on the number and types of the formal parameters
  618. only.  The type of the return value is not significant in overload
  619. resolution.
  620.  
  621. In this case there are three constructors.  The constructor which
  622. is actually called is selected by the number and types of the
  623. parameters in the definition.  In line 77 of the main program the
  624. three objects are declared, each with a different number of
  625. parameters and inspection of the results will indicate that the
  626. correct constructor was called based on the number of parameters.
  627.  
  628. In the case of the other overloaded methods, the number and type
  629. of parameters is clearly used to select the proper method.  You
  630. will notice that one method uses a single integer and another uses
  631. a single float type variable, but the system is able to select the
  632. correct one.  As many overloadings as desired can be used provided
  633. that all of the parameter patterns are unique.
  634.  
  635. You may be thinking that this is a silly thing to do but it is, in
  636. fact, a very important topic.  Throughout this tutorial we have
  637. been using an overloaded operator and you haven't been the least
  638. confused over it.  It is the cout operator which operates as an
  639. overloaded function since the way it outputs data is a function of
  640. the type of its input variable or the field we ask it to display.
  641. Many programming languages have overloaded output functions so you
  642. can output any data with the same function name.
  643.  
  644. Be sure to compile and execute this program.
  645.  
  646.  
  647.  
  648.                                                         Page 6-11
  649.  
  650.                                    Chapter 6 - More Encapsulation
  651.  
  652.  
  653. SEPARATE COMPILATION
  654. _________________________________________________________________
  655.  
  656. Separate compilation is available with C++ and it follows the
  657. identical rules as given for ANSI-C separate compilation.  As
  658. expected, separately compiled files can be linked together.
  659. However, since classes are used to define objects, the nature of
  660. C++ separate compilation is considerably different from that used
  661. for ANSI-C.  This is because the classes used to create the objects
  662. are not considered as external variables, but as included classes.
  663. This makes the overall program look different from a pure ANSI-C
  664. program.  Your programs will take on a different appearance as you
  665. gain experience in C++.
  666.  
  667.  
  668. ANOTHER PRACTICAL EXAMPLE
  669. _________________________________________________________________
  670.  
  671. Once again we come to the practical part of this lesson where we
  672. study a practical class that can actually be used in a program but
  673. is still simple enough for the student to completely understand.
  674.  
  675. In the last chapter we studied the date class    ================
  676. and in this chapter we will study a simple time       TIME.H
  677. class.  You should begin by studying the file    ================
  678. named TIME.H which will look very similar to the
  679. date class header.  The only major difference in
  680. this class from the date class is the overloaded constructors and
  681. methods.  The program is a very practical example that illustrates
  682. very graphically that many constructor overloadings are possible.
  683.  
  684. The implementation for the time class is given   ================
  685. in the file named TIME.CPP.  Once again, the         TIME.CPP
  686. code is very simple and you should have no       ================
  687. problem understanding this example in its
  688. entirety.  It should be pointed out that three
  689. of the four overloadings actually call the fourth so that the code
  690. did not have to be repeated four times.  This is a perfectly good
  691. coding practice and illustrates that other member functions can be
  692. called from within the implementation.
  693.  
  694. The example program named USETIME.CPP is a very   ===============
  695. simple program that uses the time class in a        USETIME.CPP
  696. very rudimentary way as an illustration for you.  ===============
  697. You should be able to understand this program in
  698. a very short time.  It will be to your advantage
  699. to completely understand the practical example programs given at
  700. the end of the last chapter and the end of this chapter.  As
  701. mentioned above, we will use the time class and the date class as
  702. the basis for both single and multiple inheritance in the next
  703. three chapters.
  704.  
  705.  
  706.  
  707.                                                         Page 6-12
  708.  
  709.                                    Chapter 6 - More Encapsulation
  710.  
  711.  
  712. WHAT SHOULD BE THE NEXT STEP?
  713. _________________________________________________________________
  714.  
  715. At this point you have learned enough C++ to write meaningful
  716. programs and it would be to your advantage to stop studying and
  717. begin using the knowledge you have gained.  Because C++ is an
  718. extension to ANSI-C, it can be learned in smaller pieces than would
  719. be required if you are learning a completely new language.  You
  720. have learned enough to study and completely understand the example
  721. program given in chapter 12, the Flyaway adventure game.  You
  722. should begin studying this program now.
  723.  
  724. One of your biggest problems is learning to think in terms of
  725. object oriented programming.  It is not a trivial problem if you
  726. have been programming in procedural languages for any significant
  727. length of time.  However, it can be learned by experience, so you
  728. should begin trying to think in terms of classes and objects
  729. immediately.  Your first project should use only a small number of
  730. objects and the remainder of code can be completed in standard
  731. procedural programming techniques.  As you gain experience, you
  732. will write more of the code for any given project using classes and
  733. objects but every project will eventually be completed in
  734. procedural code.
  735.  
  736. After you have programmed for a while using the techniques covered
  737. up to this point in the tutorial, you can continue on to the next
  738. few chapters which will discuss inheritance and virtual functions.
  739.  
  740.  
  741. PROGRAMMING EXERCISES
  742. _________________________________________________________________
  743.  
  744. 1.   Modify OBJDYNAM.CPP to make the objects named small and medium
  745.      pointers, then dynamically allocate them prior to using them.
  746.  
  747. 2.   Modify the loop in line 61 of OBJLINK.CPP so that the loop
  748.      will store 1000 elements in the list before stopping.  You
  749.      will probably wish to remove the printout from line 74 so the
  750.      program will stop in a reasonable time.  You may also get an
  751.      integer overflow indicated by wrong answers if you send a
  752.      message to get_area() with such large numbers.  That will
  753.      depend upon your compiler.  You should also add a test to
  754.      assure that the memory did not become exhausted after each
  755.      dynamic allocation.
  756.  
  757. 3.   Write a program that uses both the date and time classes in
  758.      a meaningful manner.  No answer will be given in the ANSWERS
  759.      directory for this exercise since it is so straight forward.
  760.      These classes can be used in all of your future C++ programs
  761.      to time stamp the time and date of execution.
  762.  
  763.  
  764.  
  765.  
  766.                                                         Page 6-13
  767.