【发布时间】:2011-10-17 05:19:51
【问题描述】:
我需要从同一个类的静态成员函数中调用一个非静态成员函数。 静态函数是回调。它只能接收 void 作为数据,尽管我传递了一个 char*。所以我不能直接将类实例提供给回调。我可以将结构而不是 char 传递给回调函数。任何人都可以提供例如代码以在静态成员函数中使用非静态成员函数。并且使用静态成员函数中的结构来使用类的实例来调用非静态成员函数?
【问题讨论】:
我需要从同一个类的静态成员函数中调用一个非静态成员函数。 静态函数是回调。它只能接收 void 作为数据,尽管我传递了一个 char*。所以我不能直接将类实例提供给回调。我可以将结构而不是 char 传递给回调函数。任何人都可以提供例如代码以在静态成员函数中使用非静态成员函数。并且使用静态成员函数中的结构来使用类的实例来调用非静态成员函数?
【问题讨论】:
通常这样的回调应该是这样的:
void Callback( void* data)
{
CMyClass *myClassInstance = static_cast<CMyClass *>(data);
myClassInstance->MyInstanceMethod();
}
当然,您需要确保数据指向您的类的实例。例如
CMyClass* data = new CMyClass();
FunctionCallingMyCallback( data, &Callback);
delete data;
现在,如果我理解正确,您还需要传递一个 char*。 您可以将两者包装在一个结构中并在回调中解开它,如下所示:
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 的定义,则将所有必要的数据放在类成员中,这样您就可以像第一个示例一样使用回调。
【讨论】:
如果您的实例是单例(通常使用私有或受保护的构造函数和指向自身的静态指针来实现),您可以这样做,例如:
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();
}
【讨论】:
getInstance 方法结合私有/受保护的构造函数允许您限制对单个实例的访问。
这是唯一的方法:
#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();
}
【讨论】:
我需要从静态成员调用非
static成员函数 相同class的功能。static函数是一个回调。它可以 只接收 void 作为数据,尽管我传递了char*。
这表明当前的设计有缺陷或不恰当。恕我直言,您应该考虑更改设计。试想一下,如果您以某种方式使事情正常运行,但代码的可维护性和可读性又会如何。
我建议你应该将你的回调函数更改为不同的签名并进行相应的更改。
class A {
//...
static void CallBack (A *pObj)
{
// logic
}
};
【讨论】: