2013-07-28 3 views
0

저는 SDL2_mixer 라이브러리를 사용하고 있습니다 만,이 질문은 일반적인 경우에도 마찬가지라고 생각합니다.매개 변수를 변경하지 않고 콜백 범위를 변경할 수있는 방법이 있습니까?

현재 내가 사용하고자하는 함수 인 Mix_HookMusicFinished(void (*music_finished)(void))에는 C 스타일 함수의 전역 범위에 대한 콜백이 설정되어 있습니다. 그러나 그 콜백은 내 전역 클래스의 함수를 사용할 필요없이 내 클래스 void CMusic::musicFinished() 내의 멤버 함수로 설정해야합니다.

어쨌든 이것을 할 수 있습니까? Mix_HookMusicFinished(musicFinished)과 같은 것이 좋겠지 만 직접적으로 오류가 있습니다. argument of type "void (CMusic::*)()" is incompatible with parameter of type "void (*)()"

답변

1

"래퍼"기능을 만들어야합니다. 그러나 문제는 여기에 당신은 또한 "마무리"에 원하는 CMusic 개체를 찾을 수 있어야한다는 것입니다 -이 유형의

인수의 핵심은 ...와 호환이 무엇인지 정말 ..

이 전부입니다. musicFinished 객체에 매개 변수를 전달할 방법이 없으므로 CMusic 객체를 "찾는"다른 방법이 필요합니다.

class CMusic 
{ 
    ... 

public: 
    ... 
    static void musicFinishedWrapper(); 
    void musicFinished(); 
    ... 
}; 


void CMusic::musicFinishedWrapper() 
{ 
    CMusic* music = getTheMusicSomehow(); // No idea how you do this - depends on your code. 

    music->musicFinished(); 
} 

당신이 CMusic 객체가 musicFinished은 (숨겨진) this 포인터 인수를 기대하는 것이다 가져야하는 이유 : 우리는 다음과 같은 일이 일 것이라고 할 수있는 방법이 가정하면

내 작은 기능으로는 music의 값입니다.

1

musicFinishedCMusic 클래스로 옮기고 static 클래스 메소드로 선언 할 수 있습니다. static 클래스 메서드는 객체에서 호출되지 않습니다. 따라서 그들은 포인터의 값을 지정하는 함축적 인 인수를 가지지 않으므로 독립 실행 형 함수와 동일한 서명을 가질 수 있습니다. CMusic 이외의 것을 방지하려면 추가로 private을 만들 수 있습니다. 당신의 musicFinished 방법은 현재 protected 또는 private 회원, 그 범위를 제한하기 위해 노력하기 때문에 CMusic의 액세스를 필요로하지 않는다, 따라서 아마도 독립형 기능으로 작동하고 있기 때문에

그러나, 아마도 다른 원하지 않는 것을 의미한다 그것을 부르는 것, 나는 개인적으로 당신의 musicFinished을 freestanding으로 남겨두고, CMusic 소스 (.cpp 또는 .cc) 파일 내의 static (또는 원하는 경우 익명의 네임 스페이스로 이동)으로 선언하십시오. 그렇게하면 범위를 소스 파일 ("컴파일 단위")로 제한합니다. private, static 클래스 메서드보다 장점은 헤더 파일에 전혀 노출 될 필요가 없으므로 좀 더 개인적인 것입니다.

관련 문제