Как вызвать нестатическую функцию-член из статической функции-члена, не передавая экземпляр класса - PullRequest
4 голосов
/ 01 августа 2011

Мне нужно вызывать нестатическую функцию-член из статической функции-члена того же класса. Статическая функция является обратным вызовом. Он может получать только void в качестве данных, хотя я передаю символ *. Поэтому я не могу напрямую предоставить экземпляр класса для обратного вызова. Я могу передать структуру вместо char в функцию обратного вызова. Может ли кто-нибудь дать, например, код для использования нестатической функции-члена в статической функции-члене. и использовать структуру в статической функции-члене, чтобы использовать экземпляр класса для вызова нестатической функции-члена?

Ответы [ 4 ]

5 голосов
/ 01 августа 2011

Обычно такой обратный вызов будет выглядеть следующим образом:

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

Конечно, вам нужно убедиться, что данные указывают на экземпляр вашего класса.Например,

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

Теперь, если я вас правильно понимаю, вам также нужно передать символ *.Вы можете заключить оба в структуру и развернуть в обратном вызове следующим образом:

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);
}

или, если вы можете изменить определение CMyClass, поместить все необходимые данные в члены класса, чтобы вы моглииспользуйте обратный вызов, как в первом примере.

4 голосов
/ 01 августа 2011

Если ваш экземпляр является одноэлементным (обычно реализуемым с помощью закрытого или защищенного конструктора и статического указателя на себя), вы можете сделать, например ::

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();
}

Если вы не используете синглтон, но можете передать приведение экземпляра к void *, тогда вы можете сделать это вместо:

void MyClass::myCallback(void *data) {
  MyClass *instance = static_cast<MyClass *>(data);
  instance->callback();
}
0 голосов
/ 01 августа 2011

Мне нужно вызвать функцию-член не static из статической функции-члена того же class.Функция static является обратным вызовом.Он может получить только void в качестве данных, хотя я передаю char*.

. Это показывает, что существующий дизайн некорректен или недействителен .ИМХО, вам лучше подумать об изменении дизайна.Просто представьте, если вы как-то работаете, а как насчет удобства сопровождения и читабельности кода.

Я бы посоветовал вам изменить функцию обратного вызова на другую сигнатуру и внести соответствующие изменения.

class A {
//...
  static void CallBack (A *pObj)
  {
    // logic
  }
};
0 голосов
/ 01 августа 2011

Это единственный способ:

#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();
}
...