home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / lang / cplus / 16570 < prev    next >
Encoding:
Internet Message Format  |  1992-11-19  |  5.0 KB

  1. Path: sparky!uunet!mcsun!sunic!hagbard!loglule!jbn
  2. From: jbn@lulea.trab.se (Johan Bengtsson)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: question on REFERENCES
  5. Message-ID: <5239@holden.lulea.trab.se>
  6. Date: 19 Nov 92 16:10:17 GMT
  7. References: <1992Nov18.172428.15485@fcom.cc.utah.edu>
  8. Organization: Telia Research AB, Aurorum 6, 951 75 Lulea, Sweden
  9. Lines: 96
  10. X-Newsreader: Tin 1.1 PL4
  11.  
  12. swillden@news.ccutah.edu (Shawn Willden) writes:
  13. : jbn@lulea.trab.se (Johan Bengtsson) writes:
  14. : : swillden@news.ccutah.edu (Shawn Willden) writes:
  15. : : : kestes@nswc-wo.nswc.navy.mil (Kent Estes) writes:
  16. : : : : 
  17. : : : : I am working on a function that references objects via id.  Upon finding
  18. : : : : an object, it returns a reference to that object.  My question is :
  19. : : : : if the object is not found, what is the best way to handle this.  If 
  20. : : : : I were returning pointers to objects, all I would have to do is
  21. : : : : return NULL.
  22. : : : 
  23. : : : So return a pointer.  There is no way to return a NULL reference (which
  24. : : : is good, if you have a reference you *know* that it refers to something).
  25. : : : 
  26. : : : If there really is a good reason why you need to return a reference 
  27. : : : instead of a pointer you can declare a special object of the return
  28. : : : type that is always to be returned in case of error and then compare
  29. : : : the address of the returned object with the address of the error 
  30. : : : object (or overload operator== and play games with that).  Usually,
  31. : : : though, you're better off just returning a pointer.
  32. : : A better approach (IMHO) is to register errors in an error variable,
  33. : : which can be a global variable, or one per object (for member functions).
  34. : : The error variable must be explicitly read and reset, before proceeding.
  35. : How is this different from a test for NULL?  The syntax may be slightly
  36. : cleaner but not much is really gained by this approach.
  37.  
  38. You can often arrange things so that it is safe to attempt quite a few
  39. function calls without checking anything at all (the first error is
  40. safely stored away in a global variable).  If on the average you make
  41. a few (say five) function calls before testing, you get a significant
  42. reduction in the number of error tests, making the real algorithm more
  43. easily recognizable.
  44.  
  45. : Something must
  46. : still be returned and that something will be invalid if the function 
  47. : fails.  Why is the programmer more likely to remember to test an error
  48. : flag than to test a returned pointer against NULL?
  49.  
  50. Because the error flag does not go away.  A later check will detect the
  51. error.  Often this is quite acceptable, especially if the error is very
  52. rare.  Also, you can arrange for checking the error flag at program
  53. termination.  Any unhandled error at program exit can then be reported.
  54.  
  55. Similarly, if an object keeps an internal error state, then its
  56. destructor should check the error state.  If there is an error, the destructor
  57. should report it when the object goes out of scope (the iostream classes
  58. do not do this, but IMHO they should).
  59.  
  60. This way you can guarantee that no errors pass unnoticed, which is
  61. impossible with the NULL return value approach.
  62.  
  63. : It can be argued 
  64. : that a program should halt for a serious programmer error such as this
  65. : so as to help the debugging process.
  66.  
  67. I guess that is what I am saying.  Iostream destructors should IMO
  68. abort the program, if any error bit (except eofbit) is set, or provide
  69. a call-back for this purpose.
  70.  
  71. [...]
  72. : In the case of a 
  73. : function that returns an object, however, how do you prevent the 
  74. : object returned from being used?  You must include a flag in the object
  75. : that indicates the goodness of the state of the object.  This is 
  76. : reasonable in some cases, not in others, depending on how serious
  77. : the failure is (i.e. maybe the error is such that even an invalid
  78. : object cannot be constructed).
  79.  
  80. Agreed.  This is sometimes problematic, and you may have to resort to
  81. pointer return values for this reason.
  82.  
  83. : In addition, it requires all code
  84. : that uses an object to test its goodness and then take appropriate
  85. : action if not.  In many cases it is more convenient to design
  86. : the object such that a given instance is always valid and to just avoid
  87. : creating invalid ones.
  88.  
  89. Yes, and a nice variation is to return an object that checks the
  90. "goodness" flag itself, and performs safe default actions if it
  91. is an invalid object.  Sometimes this can be programmed by returning
  92. an object of a subclass of the return type (which is a reference),
  93. that overrides virtual functions appropriately.
  94.  
  95. : Many times beginning C++ programmers get the idea that pointers are
  96. : the `C' way to do things and references are the `C++' way (implying
  97. : that pointers should not be used in `real' C++ code).  I was trying
  98. : to point out to the original poster that pointers have their place.
  99.  
  100. I'll go along with that...
  101. -- 
  102. --------------------------------------------------------------------------
  103. | Johan Bengtsson, Telia Research AB, Aurorum 6, S-951 75 Lulea, Sweden  |
  104. | Johan.Bengtsson@lulea.trab.se; Voice:(+46)92075471; Fax:(+46)92075490  |
  105. --------------------------------------------------------------------------
  106.