CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9

Thread: function call

  1. #1
    Join Date
    Nov 2001
    Location
    Sweden
    Posts
    4

    function call

    Hi Gurus,
    I would like a class with a member function that is able to receive
    any another class member function as an argument.
    This to be able to callback anyone who calls.
    Don't know how to do this, hope for a sample or a push in the right direction.
    Thanks in advance /Tommy

  2. #2
    Join Date
    Mar 2002
    Location
    California
    Posts
    1,582

    Here's a push

    Do some research on template member functions, as in member functions that are templates in a non-template class.

    Basically, you'll need to store the class pointer and an offset to the member function.

    All of the callbacks will need to have the same number of arguments.

    I've used this before, but would be hard pressed to come up with an example.

    Jeff

  3. #3
    Join Date
    Jan 2001
    Location
    Germany, Bavaria
    Posts
    61
    Hi Tommy,

    this is quite complicated Pointers to member functions are tricky because you always need a valid 'this'-pointer to an object on which the member is invoked (as long as the member is not static).

    If you really want to use this then search for 'functors'. You can find some here: http://www.crupp.de/prj/EventSystem.cpp.html

    It's a message queue system with callback functions. Maybe it helps...

    cu
    Chris

  4. #4
    Join Date
    Jan 2000
    Posts
    7

    Example

    I think some templates and inheritance will do the trick, but it will not be pretty... take a deep breath

    Code:
    class CallbackBase {
    public:
      CallbackBase() {}
      virtual ~CallbackBase() {}
    };
    
    // My c++ grammar is a bit shaky on pointers to member
    // functions and how to use them, but here is a try:
    template <class T>
    class Callback : public CallbackBase {
    public:
      Callback(T* obj, void (T::*memberFunc) ())
        : _obj(obj), _memberFunc(memberFunc)
      {}
    
      void Notify()
      {
        // call member function using _obj and _memberFunc
        _obj->(*_memberFunc)();
      }
    
    private:
      T* _obj;
      void (T::*_memberFunc) ();
    };
    
    // To use this stuff:
    
    void
    MyClass::CallbackAtOnce(CallbackBase *cb)
    {
      cb->Notify();
      delete cb;
    }
    
    void
    CallingClass::TestCallback()
    {
      MyClass myClass;
    
      myClass.CallbackAtOnce(
        new Callback<CallingClass>(this, CallbackFunc)
      );
    }
    
    void
    CallingClass::CallbackFunc()
    {
      cout << "Finally there!" << endl;
    }
    By using a non-template base class it is possible to handle the callback function object as a CallbackBase object. Someone may please tell me an easier way to do this stuff, but this is the best I have come up with (yet)...

    Good luck

    /Stefan

  5. #5
    Join Date
    Apr 2001
    Location
    Brisbane, Australia
    Posts
    17
    Implementing callbacks are very easy once you understand the basic mechanism.

    First you need to declare a static method in your class:

    Code:
    Class CMyClass
    {
    static void __cdecl myThreadWrapper(LPVOID);
    };
    Then in the class file, declare the method:


    Code:
    void CMyClass::myThreadWrapper(LPVOID ptr)
    {
    	CMyClass * mySelf=(CMyClass *)ptr;
    	CMyNewClass *pMyThread = new CMyNewClass();
    	pMyThread->MyMethod();
    	delete pMyThread;
    }
    Then, in the method that requires the callback, use the & operator and stick the static method name into the function, in this case I used the WIN32 thread call and pass a pointer to the "this" object.

    Code:
    void CMyClass::MethodThatHasACallBack()
    {
    ..
    do stuff
    ..
    _beginthread( &myThreadWrapper, 0, this );
    }

    Most Important is that you must pass the this pointer!



    Hope this helps!
    Last edited by sidy; May 16th, 2002 at 06:20 PM.
    ==========================
    Sid Young
    Sunny Queensland
    Australia (Oz)

  6. #6
    Join Date
    Oct 2001
    Location
    Chicago, USA
    Posts
    222
    Stefan Langemark

    So basically this is how you would acheive the event model used in java swnig?? i mean this would be equivalent in c++ is it??

  7. #7
    Join Date
    Apr 2001
    Location
    Brisbane, Australia
    Posts
    17

    Thumbs up

    Howdy,

    I ripped this straight out of production C++ code... I would not imagine Java to have a problem with callbacks.

    Sid
    ==========================
    Sid Young
    Sunny Queensland
    Australia (Oz)

  8. #8
    Join Date
    Jan 2000
    Posts
    7

    interface pointer

    Of course it is also possible to make callbacks the easy (traditional, boring?) way by declaring an interface (class) with only one virtual abstract member and then letting all classes that want callbacks implement that interface. Then you only need to pass the interface pointer around... But then the name of the callback function is of course fixed. This is also the beginning of the observer pattern...

    ankursaxena, I do not use Java or Swing, so I am not the right person to compare it with c++

    /Stefan

  9. #9
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    It all depends on why you want the callback. There are a number of design patterns that might be relevant:

    1) Chain of responsibility. Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.

    2) Command. This encapsulates a request as an object, allowing you to parameterise clients with different requests, queue or log requests, and support undoable operation

    3)Mediator. Define an object that encapsulates how a set of objects interact.

    4) Observer. Define a one-to-many dependency between objects, so that when one object changes state, all its dependents are notified.

    5) Visitor. (Possibly) Extend the operations that can be performed on/by a class hierarchy without extending the class interfaces.

    (All descriptions taken from the GoF book).
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured