2011-08-01 125 views
4

我需要從同一個類的靜態成員函數中調用非靜態成員函數。 靜態函數是一個回調函數。它可以只接收無效的數據,雖然我通過一個char *。所以我不能直接向回調提供類實例。我可以將結構而不是char傳遞給回調函數。任何人都可以給例如代碼在靜態成員函數中使用非靜態成員函數。並使用靜態成員函數中的結構來使用該類的實例來調用非靜態成員函數?如何從靜態成員函數中調用非靜態成員函數而不通過類實例

回答

5

通常這樣的回調應該是這樣的:

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的定義,把類成員的所有必要的數據,這樣就可以使用如第一個例子中的回調。

+0

好的答案 - +1 - 但你不應該使用C風格的演員恕我直言。 – sje397

+0

@ sje397 - 同意,但是這是SO,每秒都在計數。將編輯... – Henrik

+0

感謝亨裏克它的工作。我之前嘗試過同樣的事情,除了我爲該結構創建了一個指針。 – HariHaraSudhan

0

這是唯一的出路:

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

如果您的實例是單身,你可以做(​​通常是使用私有或受保護的構造和靜態指針本身實現的),例如:

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

它接縫的getInstance是有用的,以便進入類的名稱空間。是對的嗎?這是唯一的目的嗎? – Jonathan

+0

@Jonathan將getInstance方法與private/protected構造函數結合使用,可以限制對單個實例的訪問。 – sje397

+0

您可以添加到您的第一個示例不同的靜態回調「myCallback <1-4>」調用與const參數相同的方法MyClass ::回調。用XMacro定義「myCallback <1-4>」會很好。 – Jonathan

0

我需要從同一class的靜態成員函數 調用非static成員函數。 static函數是一個回調函數。它可以 只接收無效的數據,雖然我通過char*

這表明本設計是有缺陷的或inproper。恕我直言,你應該考慮改變設計。試想一下,如果你以某種方式獲得工作,但可維護性和代碼的可讀性如何呢?

我建議你應該改變你的回調函數到不同的簽名,並根據變化。

class A { 
//... 
    static void CallBack (A *pObj) 
    { 
    // logic 
    } 
};