Thread: syntax to pass a member function pointer to another class?

  1. #1
    Registered User
    Join Date
    Oct 2003
    Posts
    50

    syntax to pass a member function pointer to another class?

    hey,

    i'm having trouble working out what the syntax is when you want to pass a member function of a class (from a another member function of that class) to another function (which is a member of another class)...

    like this:
    Code:
    typedef void(*FnToCallback)(void);
    
    class B
    {
    public:
    void Register(FnToCallback passedInFnToCallback);
    void FnThatCallsBackLater();
    
    private:
    FnToCallback storedFnToCallback;
    };
    
    
    class A
    {
    public:
    A(B classToRegisterTo);
    void CallbackFunction();
    };
    
    B instanceOfB;
    A instanceOfA(instanceOfB);
    
    A::A(B classToRegisterTo)
    {
        	classToRegisterTo.Register(CallbackFunction);
    }
    
    void A::CallbackFunction()
    {
    //does something useful
    }
    
    
    void B::Register(FnToCallback passedInFnToCallback)
    {
     storedFnToCallback = passedInFnToCallback;
    }
    
    void B::FnThatCallsBackLater()
    {
    storedFnToCallback()
    }
    
    int main()
    {
    //lots of code
    instanceOfB.FnThatCallsBackLater();
    //more code
    }
    i think that makes sense

    anyway, as it stands, i get an error like this:
    cannot convert parameter 1 from 'void (void)' to 'void (__cdecl *)(void)'

    i think the problem is that i am trying to pass a pointer to a member function, because if i create a test global function and try to pass that, it works.

    thanks in advance to anyone who can decipher all that and help
    Last edited by reanimated; 11-27-2003 at 03:33 PM.

  2. #2
    Registered User
    Join Date
    Oct 2003
    Posts
    50
    a large cup of coffee has kinda lifted the haze, and its occured to me its nonsense tryng to pass a member function pointer, you need to pass an object pointer, and then call that objects callback method.

    so i tried this:

    Code:
    void B::Register(A* objectToCallBack)
    {
    //stores the parameter
    }
    
    void B::FnThatCallsBackLater()
    {
    storedObjectPointer->Callback();
    }
    
    A::A(B* classToRegisterTo)
    {
    B->Register(this);
    }
    when that code executes however, i get an access violation. although the debugger shows the stored object address and actual object address are the same... which leaves me confused

  3. #3
    Registered User glUser3f's Avatar
    Join Date
    Aug 2003
    Posts
    345
    you can't make:
    void (*callback)(void);
    point to:
    void A::member_func(void);
    you need to use:
    Code:
    void (A::*callback)(void);
    callback = A::member_func;
    more info here:
    http://www.vmlinux.org/jakov/communi...com/15837.html

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    This is where functors come in handy:



    Code:
     struct functor_type
    {
     virtual void operator ()(void) {};
    };
    
    
    template <class type>
     struct functor : functor_type
    {
      functor()
     {
      self = 0;
      function = 0;
     }
      functor(type * _this, void (type::*some_function)(void))
     {
      make(_this, some_function);
     }
      functor & make(type * _this, void (type::*some_function)(void))
     {
      self = _this;
      function = some_function;
      return *this;
     }
      void operator ()(void)
     {
      (*self.*function)(); // can't use self->function()!
     }
     type * self;
     void (type::*function)(void);
    };


    Notice that the above just covers functions that take no parameters and return nothing. In other words, for every possible function signature you need, you have to code a corresponding functor method. That's one drawback with functors.


    Anyway, now you just plug this into the classes themselves. Notice that class 'b' doesn't need to know what type of class gave it a functor, but class 'a' does have to parameterize it's template:



    Code:
     struct b
    {
      void Register(functor_type & passedInFnToCallback)
     {
      callback = passedInFnToCallback;
     }
      void FnThatCallsBackLater()
     {
      callback();
     }
     b()
      :callback(dummy)
     {
    
     }
     functor_type & callback, dummy;
    };
    
    
    
     struct a
    {
      a(b & B)
     {
      callback.make(this, &a::Callback);
    
      B.Register(callback);
     }
      void Callback()
     {
      cout << "Hello from 'a'" << endl;
     }
     functor<a> callback;
    };


    Example:



    Code:
    int main()
    {
     b b;
     a a(b);
     b.callback();
     return cin.get();
    }


    Hope that helps.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  5. #5
    Registered User
    Join Date
    Oct 2003
    Posts
    50
    thank you for your help

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  2. Calling a Thread with a Function Pointer.
    By ScrollMaster in forum Windows Programming
    Replies: 6
    Last Post: 06-10-2006, 08:56 AM
  3. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM
  4. Staticly Bound Member Function Pointers
    By Polymorphic OOP in forum C++ Programming
    Replies: 29
    Last Post: 11-28-2002, 01:18 PM
  5. Function pointer to class member?
    By no-one in forum C++ Programming
    Replies: 2
    Last Post: 04-22-2002, 08:23 PM