home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!rutgers!cmcl2!acf5!checker
- From: checker@acf5.NYU.EDU (checker)
- Newsgroups: comp.lang.c++
- Subject: Re: Callbacks - C++ needs an extension?
- Keywords: callback event eventdriven extension
- Message-ID: <1893@acf5.NYU.EDU>
- Date: 29 Aug 92 19:26:35 GMT
- References: <1992Aug28.165108.17479@isy.liu.se> <1992Aug29.161356.16729@genghis.borland.com>
- Organization: New York University
- Lines: 73
-
- pete@genghis.borland.com (Pete Becker) writes:
- > The most straightforward solution is to work with the library and
- >provide a callback function that examines the message being sent and forwards
- >it to the appropriate recipient.
-
- I hope by straightforward you don't mean most secure, easiest to debug,
- or even easiest to maintain. There is a simple way of doing blind
- callbacks in a typesafe manner using an intermediary class and a pure
- virtual function:
-
- class callback
- {
- public:
- virtual void CallBack( void ) = 0;
- };
-
- This is the interface class. An object that needs to call another
- object back takes a reference to one of these:
-
- class button
- {
- public:
- button( callback &CalledWhenPushed, etc. );
- };
-
- Now, any object that wants to instantiate a button and be called back
- simply derives from callback:
-
- class my_callback :
- public callback
- {
- public:
- my_callback( my_class &Instance, void (my_class::*pToCall)( void ) );
- void CallBack( void );
- private:
- my_class &Instance;
- void (my_class::*pToCall)( void );
- };
-
- This concrete callback class takes a reference to an instance of the guy
- who wants to be called back, and a pointer to one of his member
- functions. The class obviously stores that information inside itself:
-
- my_callback::my_callback( my_class &I, void (my_class::*p)( void ) ) :
- Instance(I), pToCall(p)
- {
- }
-
- The CallBack function simply calls the member function:
-
- void my_callback::CallBack( void )
- {
- (Instance.*pToCall)();
- }
-
- Now, inside my_class I would do this to instantiate a my_callback:
-
- my_callback MyCB(*this,&my_class::MyFunction);
-
- then I'd pass this object to the button using the standard conversion:
-
- button MyButton(MyCB,...);
-
- That's it. button knows absolutely nothing about who it is calling.
- The method uses the virtual call mechanism so it is completely type
- safe. There is no run time switching on message types, etc, and the
- method is easily extended using templates and/or nested classes.
-
- This technique is a typical use of the abstract interface/concrete
- implementation idea. All of the grungy details are in the derived
- class, so the folks using the base don't have to know about them.
-
- Chris
-