Пару дней назад на работе зашел разговор о том, как можно использовать указатели на методы в 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++). А так все просто, прозрачно и эффективно.