Path: utzoo!utgpu!news-server.csri.toronto.edu!clyde.concordia.ca!uunet!cs.utexas.edu!milano!cadillac!vaughan@mcc.com From: vaughan@mcc.com (Paul Vaughan) Newsgroups: comp.lang.c++ Subject: Re: Again: Pointer to methods ? Keywords: Pointers to methods Message-ID: <10358@cadillac.CAD.MCC.COM> Date: 11 Aug 90 21:13:28 GMT References: <2292@zgdvda.zgdvda.uucp> Sender: news@cadillac.CAD.MCC.COM Reply-To: vaughan@mcc.com (Paul Vaughan) Organization: MCC VLSI CAD Program Lines: 141 In-reply-to: dingelde@viktoria.grz (Dennis Dingeldein) I tried to mail this directly using reply, but my mail bounced. Anyway, it might be interesting to many people. dingelde@viktoria.grz (Dennis Dingeldein) wrote: Problem: 1. The method of my class needs to accept a pointer to a method of another class. MyClass::SetPointer( ) 2. At compile time of my class I don`t know anything about the other class. 3. SetPointer must be a *method* (of my class), no C function. 4. A solution like "Use a third class with virtual method "SetPointer" and derive from that class "SetPointer" methods with the appreciated parameters" is not the one I like to use. This seems to me like "programming around the problem because I couldn`t solve it". // main shows a menu and draws the circle on selection main() { Menu MyMenu( "Draw Circle" ); Circle MyCircle( ... ); MyMenu.SetPointer( MyCircle::Draw( ... ) ); // If the User selects an entry , the circle is drawn! Menu.Start(); } Who know's what to do ? What`s the prototype of Method "SetPointer" ? Make the function passed to SetPointer be a void (*)() instead of a member function of the other class. You can declare it statically in the code for the other class. If you need to have it call a member function, you're going to have to arrange for the object pointer to be passed in and also be stored when you do the SetPointer, like this: void MyMenu::SetPointer(void*, void (*)()) and in some other file static void myfunc(void* self) { ((Foo*) self)->Draw(); } and call MyMenu::SetPointer((Foo*) this, myfunc) at some point. Of course, this isn't completely type-safe, but it is fairly simple to manually verify type safety, given that myfunc is static and you probably only call SetPointer once in the file, and the MyMenu probably handles recording the void* and void (*)() together and doesn't mess with them much. Probably the best solution is one you arbitrarily threw out. Have some kind of menu selection class class SelectionAction { public: virtual void Select(); }; and derive specialized versions of that and pass them to the menu via SetPointer (although "SetPointer" seems like a particularly obtuse name for the function that does this). For instance for your circle object, you could either use multiple inheritance, or something like this: class MyMenu { public: void SetPointer(SelectionAction*); private: void MakeSelection(); SelectionAction* selectionAction; } void MyMenu::SetPointer(MySelection* s) { selectionAction = s; } void MyMenu::MakeSelection() { selectionAction->Select(); } and in the other file class Circle; class CircleSelectionAction { public: CircleSelectionAction(Circle*); void Select(); protected: Circle* circle; }; CircleSelectionAction::CircleSelectionAction(Circle* c) : circle(c) {} class Circle { public: Circle(); Draw(); private: CircleSelectionAction action; }; void CircleSelectionAction::Select() { circle->Draw(); } Circle::Circle() : action(this) //It may be better to make action pointer and initialize it in the //constructor body. That way you could take CircleSelectionAction out //of the .h file above and avoid cluttering your name spaces. But //then you have to use a destructor to get rid of it. and at some point call MyMenu::SetPointer(&this->action); If you need additional arguments passed into the Draw function, you can put them into the action object. If you decide to pass additional arguments to the Select method, that's easy enough to do. -- Paul Vaughan, MCC CAD Program | ARPA: vaughan@mcc.com | Phone: [512] 338-3639 Box 200195, Austin, TX 78720 | UUCP: ...!cs.utexas.edu!milano!cadillac!vaughan Paul Vaughan, MCC CAD Program | ARPA: vaughan@mcc.com | Phone: [512] 338-3639 Box 200195, Austin, TX 78720 | UUCP: ...!cs.utexas.edu!milano!cadillac!vaughan