Страницы

Поиск по вопросам

пятница, 20 декабря 2019 г.

CallBack функция как член класса

#callback #cpp


Возможно ли использовать CallBack вызовы при написании своих классов (на С++, под
OS Windows)?
К примеру реализовать таймер при использовании Callback в своём классе!?
  SetTimer(NULL, 0, 1000, (TIMERPROC) TimerProc)
  void CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
    


Ответы

Ответ 1



В общем виде передать указатель на нестатический, наверное, не получится. Но конкретно описываемую Вами задачу можно решить, например, так. Экземпляры классов, которые хотят получать уведомления от таймера регистрируются в некотором словаре, получая при этом идентификатор таймера. Обработчик таймера находит получателя по идентификатору таймера и переадресует вызов ему. Грубый пример: static int s_counter = 0; map s_receivers; class ITimerReciever { public: virtual void OnTimer() = 0; } static void AdviseToTimer(UINT elapse, ITimerReceiver * pReceiver) { receivers[++s_counter] = pReceiver; SetTimer(NULL, s_counter, elapse, (TIMERPROC) TimerProc); } void CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) { receivers[idEvent]->OnTimer(); }

Ответ 2



@reije, хочу конкретный пример что хотите сделать. В общем случае - это плохая идея. С другой стороны, запросто можно получить адрес static-функции-члена класса, но есть нюанс, связанный с тем, что статическая ф-ция может получить доступ только к статическим членам класса. Т.е. по сути мы всего лишь засовываем нашу чудесную обычную функцию в namespace класса. Другой вопрос, что static ф-ция может получить доступ к каждому объекту своего типа, но это придется реализовать самостоятельно. Прекрасный пример использования возможностей С++ для реализации callback'ов предложен на SO. Используются шаблоны std::function и std::bind В качестве обходных путей предлагается реализовать: паттерн observer систему событий и их обработчиков

Ответ 3



Если я правильно понял вопрос, требуется использовать методы класса как функции обратного вызова. Это стандартная вещь: class Example { public: static void member(); }; int main() { signal(SIGINT, Example::member); }

Ответ 4



Да конечно, можно.

Комментариев нет:

Отправить комментарий