How to call a non static member function from a st

2019-02-10 20:25发布

I need to call a non static member function from a static member function of the same class. The static function is a callback. It can receive only void as data, though which i pass a char*. So i cannot directly provide the class instance to the callback. I can pass a structure instead of char to the callback function. Can anyone give eg code to use the non static member function in a static member function . and use the structure in the static member function to use the instance of the class to call the non static member function?

4条回答
手持菜刀,她持情操
2楼-- · 2019-02-10 21:01

I need to call a non static member function from a static member function of the same class. The static function is a callback. It can receive only void as data, though which i pass a char*.

This shows that present design is flawed or inproper. IMHO, you should rather think of changing the design. Just imagine if you somehow get the things working but what about the maintainability an readability of the code.

I would suggest that you should change your callback function to different signature and made according changes.

class A {
//...
  static void CallBack (A *pObj)
  {
    // logic
  }
};
查看更多
爷的心禁止访问
3楼-- · 2019-02-10 21:04

This is the only way :

#include <iostream>
#include <cassert>

struct A;
A *oneObj = NULL;


struct A
{
  A(){
    oneObj=this;
  }
  ~A(){
    oneObj=NULL;
  }
  void foo()
  {
  }

  static void boo()
  {
    assert( NULL != oneObj );
    oneObj->foo();
  }
};

int main()
{
  A onlyOne;
  A::boo();
}
查看更多
Explosion°爆炸
4楼-- · 2019-02-10 21:07

Normally such a callback would look like this:

void Callback( void* data)
{
    CMyClass *myClassInstance = static_cast<CMyClass *>(data);
    myClassInstance->MyInstanceMethod();
}

Of course, you need to make sure, data points to an instance of your class. E.g.

CMyClass* data = new CMyClass();
FunctionCallingMyCallback( data, &Callback);
delete data;

Now, if I understand you correctly, you need to also pass a char*. You can either wrap both in a struct and unwrap it in the callback like so:

MyStruct* data = new MyStruct();
data->PtrToMyClass = new CMyClass();
data->MyCharPtr = "test";
FunctionCallingMyCallback( data, &Callback);
delete data->PtrToMyClass;
delete data;


void Callback( void* data)
{
    MyStruct *myStructInstance = static_cast<MyStruct *>(data);
    CMyClass *myClassInstance = myStructInstance->PtrToMyClass;
    char * myData = myStructInstance->MyCharPtr;
    myClassInstance->MyInstanceMethod(myData);
}

or, if you can modify the definition of CMyClass, put all the necessary data in class members, so that you can use a callback as in the first example.

查看更多
做个烂人
5楼-- · 2019-02-10 21:10

If your instance is a singleton (usually implemented using a private or protected constructor and a static pointer to itself) you can do e.g.:

class MyClass {
private:
  MyClass():myInstance(0) {}

  MyClass *myInstance;

  void callback();
public:
  ~MyClass() {}

  static MyClass *getInstance();

  static void myCallback();    
};

MyClass *MyClass::getInstance() {
  if(!myInstance) {
    myInstance = new MyClass;
  }
  return myInsance;
}    

void MyClass::callback() {
 // non-static callback
}

void MyClass::myCallback() {
  getInstance()->callback();
}

If you don't use a singleton but you can pass the instance cast to a void * then you can do this instead:

void MyClass::myCallback(void *data) {
  MyClass *instance = static_cast<MyClass *>(data);
  instance->callback();
}
查看更多
登录 后发表回答