среда, 21 апреля 2010 г.

[prog.c++] Пример использования указателей на методы в C++

Пару дней назад на работе зашел разговор о том, как можно использовать указатели на методы в C++. Штука это специфическая и применяется мной не часто, реже чем указатели на функции. Да еще, как обычно, когда нужно вспомнить яркий пример чего-нибудь, память не подсказывает ничего путного. Поэтому не смог я тогда вспомнить хорошего и убедительного примера.

А сейчас расширяю функциональность одного старого агента, в котором указатели на методы используются для замеров времен выполнения операций. Агент работает потактово, на каждом такте выполняется серия операций. Нужно мониторить максимальное и среднее времена работы каждой из них. В коде это выглядит так:

void
a_cp_service_t::do_all_periodic_actions()
   {
      measure_duration(
            m_monitors.m_avg_time_save_outgoing_pkg,
            this,
            &a_cp_service_t::handle_received_outgoing_packages );

      measure_duration(
            m_monitors.m_avg_time_handle_SR,
            this,
            &a_cp_service_t::handle_received_send_results );

      measure_duration(
            m_monitors.m_avg_time_handle_SR_pkg_ack,
            this,
            &a_cp_service_t::handle_received_SR_package_acks );

Где measure_duration – это очень простая функция-шаблон:

template< class T >
inline void
measure_duration(
   monitor_t & monitor,
   T * object,
   void (T::*method)() )
   {
      ACE_Time_Value s = ACE_OS::gettimeofday();
      (object->*method)();
      ACE_Time_Value f = ACE_OS::gettimeofday();

      monitor.add_time_slice( f - s );
   }

Т.е. указатели на методы в C++ позволили обойтись без определения каких-либо интерфейсов (к чему пришлось бы прибегнуть в Java), либо лямбда-функций-делегатов (C#/D/Scala), либо рефлексии (опять же Java, если интерфейсы не нравятся), либо макросов (если не знать, что такое указатели на методы в C++). А так все просто, прозрачно и эффективно.

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