880716a@aucs.uucp (Dave Astels) (05/31/90)
I am wondering if it is possible to pass messages in C++ indirectly. Let me explain: say I have a class X which has a member function foo(). Also, I have a variable y of type X. Rather than invoking y.foo() directly I want to store the information for later use. ie. I want to set up a callback (using X11 terminology).. to store the information that X::foo() is to be called for the object y, then do the call later (in response to some event, for example). I have done this in a UI I developed in Turbo Pascal 5.5. I have since bought Zortech C++, and wish to eventually rewrite the UI in C++. The technique in TP was implemented using generic pointers (to the object and the method entry point), and some assembly to do the actual method invocation (supplying the Self/this parameter, etc). -- - Dave Internet: 880716a@AcadiaU.CA Bitnet: 880716a@Acadia
sdm@cs.brown.edu (Scott Meyers) (06/01/90)
In article <1990May31.131937.25923@aucs.uucp> 880716a@aucs.uucp (Dave Astels) writes: >I am wondering if it is possible to pass messages in C++ indirectly. >Let me explain: say I have a class X which has a member function foo(). >Also, I have a variable y of type X. Rather than invoking y.foo() directly >I want to store the information for later use. ie. I want to set up a >callback (using X11 terminology).. to store the information that X::foo() >is to be called for the object y, then do the call later (in response to >some event, for example). I have done this in a UI I developed in Turbo >Pascal 5.5. I have since bought Zortech C++, and wish to eventually >rewrite the UI in C++. The technique in TP was implemented using generic >pointers (to the object and the method entry point), and some assembly to >do the actual method invocation (supplying the Self/this parameter, etc). Try this -- it works fine under cfront 2.0 (no assembly required): #include <iostream.h> class X { public: void foo() { cout << "Foo!\n"; } }; main() { cout << "Declaring an X called y...\n"; X y; cout << "Calling y.foo() directly..."; y.foo(); cout << "Declaring pointers...\n"; X *py; py = &y; void (X::*pxmf)(); pxmf = X::foo; cout << "Calling y.foo() indirectly..."; (py->*pxmf)(); } For details, see Lippman, p. 213ff. Scott sdm@cs.brown.edu
880716a@aucs.uucp (Dave Astels) (06/01/90)
In article <41462@brunix.UUCP> sdm@cs.brown.edu (Scott Meyers) writes: >In article <1990May31.131937.25923@aucs.uucp> 880716a@aucs.uucp (Dave Astels) writes: >>I am wondering if it is possible to pass messages in C++ indirectly. > > cout << "Declaring pointers...\n"; > X *py; > py = &y; > void (X::*pxmf)(); > pxmf = X::foo; > > cout << "Calling y.foo() indirectly..."; > (py->*pxmf)(); > } > Yes, but I want to be able to have a class to hold the indirect call, as in: class CallBack { void * instance; // address of instance to be passed the message void * method; // entry point of the method public: CallBack (void *, void *); Send (void); } Then I want to be able to set up an indirect call via something like: CallBack cb (&y, (X::*foo)()); // is the -> member syntax correct ? and later perform the call by cb.Send (); I realize that this probably can't work with virtual methods (on first consideration), but I don't think that is a problem in my case (the TP version won't either, and it works fine for what I need). The use of this: Consider a menu (for example). There is a CallBack connected to each option. When an option is selected its CallBack gets passed a `Send' message, thus invoking the proper action .. sending a message to some other object. This technique enables the construction of a very sofisticated, event-driven UI with little (if any) programming overhead to make it run, once the initial set up of all the components is performed. -- - Dave Astels Internet: 880716a@AcadiaU.CA Bitnet: 880716a@Acadia
roman@sparc7.hri.com (Roman) (06/02/90)
In article <1990Jun1.114837.11151@aucs.uucp>, 880716a@aucs.uucp (Dave Astels) writes: > [deleted] > > Yes, but I want to be able to have a class to hold the indirect call, as in: > > class CallBack { > void * instance; // address of instance to be passed the message > void * method; // entry point of the method > public: > CallBack (void *, void *); > Send (void); > } > > Then I want to be able to set up an indirect call via something like: > > CallBack cb (&y, (X::*foo)()); // is the -> member syntax correct ? > > and later perform the call by > > cb.Send (); > > I realize that this probably can't work with virtual methods (on first > consideration), but I don't think that is a problem in my case (the TP > version won't either, and it works fine for what I need). > > [deleted] > - Dave Astels > > Internet: 880716a@AcadiaU.CA > Bitnet: 880716a@Acadia The problem is not with virtuals, but with casting a method pointer to void*. After the cast the pointer is useless (you loose information necessary to call the method). What about this: class CallBack { public: virtual void Send(); }; class CallBackX : public CallBack { X* objPtr; void (X::*fPtr)(); public: CallBackX(X*,void (X::*)()); void Send() { (objPtr->*fPtr)(); } }; Unfortunatly for each X you have to define new CallBack class.