home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / lang / cplus / 20105 < prev    next >
Encoding:
Text File  |  1993-01-29  |  2.6 KB  |  94 lines

  1. Xref: sparky comp.lang.c++:20105 comp.std.c++:2148
  2. Newsgroups: comp.lang.c++,comp.std.c++
  3. From: nikki@trmphrst.demon.co.uk (Nikki Locke)
  4. Path: sparky!uunet!spool.mu.edu!agate!doc.ic.ac.uk!pipex!ibmpcug!demon!trmphrst.demon.co.uk!nikki
  5. Subject: Re: Callbacks -- suggested approaches??
  6. Reply-To: nikki@trmphrst.demon.co.uk
  7. References: <DAVIDM.93Jan25171343@consilium.com>
  8. Distribution: world
  9. Followup-To: comp.lang.c++
  10. X-Mailer: cppnews $Revision: 1.31 $
  11. Organization: Trumphurst Ltd.
  12. Lines: 77
  13. Date: Thu, 28 Jan 1993 13:27:12 +0000
  14. Message-ID: <728252832snx@trmphrst.demon.co.uk>
  15. Sender: usenet@demon.co.uk
  16.  
  17. In article <DAVIDM.93Jan25171343@consilium.com> davidm@consilium.com (David S. Masterson) writes:
  18. > I'm looking for suggestions on how to handle callback functions in C++ that
  19. > will be more standard than the one we're currently using.
  20. ..
  21. >     typedef    void    (Process::*Method)(Message*);
  22. >     struct Callback {
  23. >         Method        method
  24. >         Process*    methodthis;    // could be multi-threaded
  25. >     } table[MAXCALLBACKS];
  26. > Methods would be dispatched like:
  27. >     void Process::Dispatch(Message* m) {
  28. >         return (table[Lookup(m)].methodthis->*
  29. >             table[Lookup(m)].method)(m);
  30. >     }            
  31. > The registration method for callbacks looks like:
  32. >     void Process::Register(Method m, Process* p) {
  33. >         table[i].method = m;
  34. >         table[i].methodthis = p;
  35. >     }
  36. > and is called like:
  37. >     mainproc->Register((Method) MYProcess::callback1, myproc);
  38.  
  39. Personally, I use templates (or generics) for this sort of thing.
  40. Something like ...
  41.  
  42. class CallbackBase
  43.     {
  44. public:
  45.     virtual void despatch(Message *m) = 0;
  46.     virtual ~CallbackBase() {}    // Just in case someone creates
  47.             // a new kind of Callback which needs a destructor
  48.     };
  49.  
  50. template <class X> class Callback : public CallbackBase
  51.     {
  52.     void (X::*method)(Message *);
  53.     X& methodthis;
  54. public:
  55.     Callback(void (X::*m)(Message *), X& t) : method(m), methodthis(t) {}
  56.     void despatch(Message *m) { (methodthis->*method)(m); }
  57.     };
  58.  
  59. Your table is of CallbackBase pointers.
  60.  
  61. Methods would be dispatched like:
  62.  
  63. void Process::Dispatch(Message* m)
  64. {
  65.     table[Lookup(m)]->despatch(m);
  66. }
  67.  
  68. The registration method for callbacks looks like:
  69.  
  70. void Process::Register(CallbackBase *p)
  71. {
  72.     table[i].callback = p;
  73. }
  74.  
  75. and may be called like:
  76.  
  77. mainproc->Register(new Callback<MYProcess>(MYProcess::callback1, myproc));
  78.  
  79. You do have to take care of deleting the CallbackBase items, but that can 
  80. probably be done in the Process destructor.
  81.  
  82. [Note - code not compiled or tested, but I do use something very similar.]
  83.  
  84. -- 
  85. Nikki Locke,Trumphurst Ltd.(PC and Unix consultancy) nikki@trmphrst.demon.co.uk
  86. trmphrst.demon.co.uk is NOT affiliated with ANY other sites at demon.co.uk.
  87.