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

Вы можете переместить musicFinished в класс CMusic и объявить его как способ класса static. static методы класса не вызываются на объект; поэтому они не имеют неявного аргумента, чтобы указать значение указателя this, и поэтому они могут иметь ту же подпись, что и автономные функции. Вы также можете сделать это private, чтобы предотвратить использование ничего, кроме CMusic.

Однако, так как ваш метод musicFinished в настоящее время работает в качестве автономной функции и поэтому, вероятно, не нужен доступ к CMusic «s protected или private членов, а поскольку ваши усилия по ограничению его объема предположительно означает, что вы не хотите, чтобы другие вещи, чтобы называть это, я лично оставил бы вашу musicFinished функцией автономной, но объявляю ее static (или переместите ее в анонимное пространство имен, если хотите) в пределах источника CMusic (10). Это позволит ограничить область действия исходным файлом («единица компиляции»). Преимущество метода private, static заключается в том, что его вообще не нужно публиковать в файле заголовка, поэтому он в некотором смысле более частный.