I want to define a member function in class and use its pointer. I know that I can use static member function but the problem with it is that I can only access the static members of the class. Is there a way other than static member function to be able to get function pointer.


To be more specific: There is a library which I'm using which gets a function pointer as its input. I want to write a member function and assign its function pointer to that external library. Should I create an object of class or use this pointer to do this?

有帮助吗?

解决方案

You can get the pointer of the method, but it has to be called with an object

typedef void (T::*MethodPtr) ();
MethodPtr method = &T::MethodA;
T *obj = new T();
obj->*method();

If you need to have non-object pointer and you want to use object then you have to store instance of object somewhere, but you are restricted to use only one object (singleton).

class T {
  static T *instance;
public:
  T::T() {
    instance = this;
  }
  static void func() {
    instance->doStuff();
  }
  void doStuff() {}
};

If library supports user data for function pointers, then you may have multiple instances

class T {
public:
  static void func(void *instance) {
    ((T*)instance)->doStuff();
  }
  void doStuff() {}
};

其他提示

  • If:
  • you want to get the function pointer of a nonstatic member from within the class
  • And use it within the class:
  • Then: It can work, because when you get the member function address, there is a "this" pointer. The syntax was not obvious to me, and it may look somewhat ugly, but not TOO bad. This may not be new to the true experts, but I have wanted to have this in my bag of tricks for a long time.

Here is a complete sample program:

#include <iostream>
class CTestFncPtr
{
public:
    CTestFncPtr(int data) : mData(data)
    {
//      Switch = &CTestFncPtr::SwitchC; // Won't compile - wrong function prototype - this is type safe
        if (data == 1)
            Switch = &CTestFncPtr::SwitchA;
        else
            Switch = &CTestFncPtr::SwitchB;
    }
    void CallSwitch(char *charData)
    {
        (this->*Switch)(charData);
    }

private:
    void SwitchA(char * charData)
    {
        std::cout << "Called Switch A " << "Class Data is " << mData<<" Parameter is " << charData<< "\n";
        Switch = &CTestFncPtr::SwitchB;
    }
    void SwitchB(char * charData)
    {
        std::cout << "Called Switch B " << "Class Data is " << mData<<" Parameter is " << charData<< "\n";
        Switch = &CTestFncPtr::SwitchA;
    }
    void SwitchC()
    {
    }
    void(CTestFncPtr::*Switch)(char * charData);
    int mData;
};

int main(int argc, char * argv[])
{
    CTestFncPtr item1(1);
    item1.CallSwitch("Item1");
    item1.CallSwitch("Switched call Item 1");
    CTestFncPtr item2(0);
    item2.CallSwitch("Item2");
    item2.CallSwitch("Switched call Item 2");

    return 0;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top