2011-08-01 4 views
4

같은 클래스의 정적 멤버 함수에서 비 정적 멤버 함수를 호출해야합니다. static 함수는 콜백입니다. 그것은 단지 데이터로 void를받을 수 있지만 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 *를 전달해야합니다. 당신이 CmyClass에서의 정의를 수정할 수있는 경우 사용할 수 있도록 클래스 멤버에 필요한 모든 데이터를 입력,

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

또는 : 당신은 구조체 모두를 포장 할 수 있습니다 그래서 같은 콜백을 풀다 첫 번째 예제와 같은 콜백

+0

좋은 답변 - +1 -하지만 당신은 c-style 캐스트 IMHO를 사용해서는 안됩니다. – sje397

+0

@ sje397 - 동의했지만, 이것은 매 초마다 계산됩니다. 편집 할 것입니다 ... – Henrik

+0

감사 Henrick 그것이 일했습니다. 나는 구조체에 대한 포인터를 생성하는 것을 제외하고는 이전에 같은 것을 시도했다. – 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 :: callback을 호출 할 수 있습니다. XMacro로 "myCallback <1-4>"을 정의하는 것이 좋습니다. – Jonathan

0

I는 동일한 class의 고정 부재 함수의 비 static 멤버 함수를 호출 할 필요가있다. static 함수는 콜백입니다. 은 char*을 전달하지만 데이터로 void 만받을 수 있습니다.

이것은 현재 디자인이 결함 또는 불완전한임을 보여줍니다. IMHO, 당신은 오히려 디자인을 바꾸는 것을 생각해야합니다. 상상해보십시오. 어떻게 든 작동하도록 만들면 유지 보수 가능성은 코드의 가독성에 대한 것입니다.

콜백 함수를 다른 서명으로 변경하고 변경 사항에 따라 변경해야한다고 제안합니다.

class A { 
//... 
    static void CallBack (A *pObj) 
    { 
    // logic 
    } 
}; 
관련 문제