Самое важное использование указателей на членов - это создание функторов. Хорошей новостью является то, что вам даже не нужно использовать его напрямую, так как он уже решен в библиотеках как boost :: bind, но вы должны передавать указатели этим библиотекам.
class Processor
{
public:
void operation( int value );
void another_operation( int value );
};
int main()
{
Processor tc;
boost::thread thr1( boost::bind( &Processor::operation, &tc, 100 ) );
boost::thread thr2( boost::bind( &Processor::another_operation, &tc, 5 ) );
thr1.join();
thr2.join();
}
Вы можете увидеть простоту создания потока, который выполняет данную операцию над данным экземпляром класса.
Простой ручной подход к указанной выше проблеме заключается в создании собственного функтора:
class functor1
{
public:
functor1( Processor& o, int v ) : o_(o), v_(v) {}
void operator()() {
o_.operation( v_ ); // [1]
}
private:
Processor& o_;
int v_;
};
и создайте отдельную для каждой функции-члена, которую вы хотите вызвать. Обратите внимание, что функтор одинаков для операции и для операции another_operation , но вызов в [1] должен быть повторен в обоих функторах. Используя указатель на функцию-член, вы можете написать простой функтор:
class functor
{
public:
functor( void (*Processor::member)(int), Processor& p, int value )
: member_( member ), processor_(p), value_( value ) {}
void operator()() {
p.*member(value_);
}
private:
void (*Processor::member_)(int);
Processor& processor_;
int value;
};
и используйте его:
int main() {
Processor p;
boost::thread thr1( functor( &Processor::operation, p, 100 ) );
boost::thread thr2( functor( &Processor::another_operation, p, 5 ) );
thr1.join();
thr2.join();
}
Опять же, вам даже не нужно определять этот функтор, так как boost :: bind сделает это за вас. Будущий стандарт будет иметь свою собственную версию bind в соответствии с реализацией Boost.