home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / lang / cplus / 13059 < prev    next >
Encoding:
Text File  |  1992-08-29  |  2.5 KB  |  85 lines

  1. Path: sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!rutgers!cmcl2!acf5!checker
  2. From: checker@acf5.NYU.EDU (checker)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Callbacks - C++ needs an extension?
  5. Keywords: callback event eventdriven extension
  6. Message-ID: <1893@acf5.NYU.EDU>
  7. Date: 29 Aug 92 19:26:35 GMT
  8. References: <1992Aug28.165108.17479@isy.liu.se> <1992Aug29.161356.16729@genghis.borland.com>
  9. Organization: New York University
  10. Lines: 73
  11.  
  12. pete@genghis.borland.com (Pete Becker) writes:
  13. >    The most straightforward solution is to work with the library and
  14. >provide a callback function that examines the message being sent and forwards
  15. >it to the appropriate recipient.
  16.  
  17. I hope by straightforward you don't mean most secure, easiest to debug,
  18. or even easiest to maintain.  There is a simple way of doing blind
  19. callbacks in a typesafe manner using an intermediary class and a pure
  20. virtual function:
  21.  
  22. class callback
  23. {
  24. public:
  25.     virtual void CallBack( void ) = 0;
  26. };
  27.  
  28. This is the interface class.  An object that needs to call another
  29. object back takes a reference to one of these:
  30.  
  31. class button
  32. {
  33. public:
  34.     button( callback &CalledWhenPushed, etc. );
  35. };
  36.  
  37. Now, any object that wants to instantiate a button and be called back
  38. simply derives from callback:
  39.  
  40. class my_callback :
  41.     public callback
  42. {
  43. public:
  44.     my_callback( my_class &Instance, void (my_class::*pToCall)( void ) );
  45.     void CallBack( void );
  46. private:
  47.     my_class &Instance;
  48.     void (my_class::*pToCall)( void );
  49. };
  50.  
  51. This concrete callback class takes a reference to an instance of the guy
  52. who wants to be called back, and a pointer to one of his member
  53. functions.  The class obviously stores that information inside itself:
  54.  
  55. my_callback::my_callback( my_class &I, void (my_class::*p)( void ) ) :
  56.     Instance(I), pToCall(p)
  57. {
  58. }
  59.  
  60. The CallBack function simply calls the member function:
  61.  
  62. void my_callback::CallBack( void )
  63. {
  64.     (Instance.*pToCall)();
  65. }
  66.  
  67. Now, inside my_class I would do this to instantiate a my_callback:
  68.  
  69. my_callback MyCB(*this,&my_class::MyFunction);
  70.  
  71. then I'd pass this object to the button using the standard conversion:
  72.  
  73. button MyButton(MyCB,...);
  74.  
  75. That's it.  button knows absolutely nothing about who it is calling.
  76. The method uses the virtual call mechanism so it is completely type
  77. safe.  There is no run time switching on message types, etc, and the
  78. method is easily extended using templates and/or nested classes.
  79.  
  80. This technique is a typical use of the abstract interface/concrete
  81. implementation idea.  All of the grungy details are in the derived
  82. class, so the folks using the base don't have to know about them.
  83.  
  84. Chris
  85.