Я столкнулся с этой проблемой пару месяцев назад, работая над своим старшим дизайнерским проектом.Это требует определенных знаний о базовой механике C ++.
Основная проблема заключается в том, что указатели на функции отличаются от указателей на функции-члены.Это связано с тем, что функции-члены имеют неявный первый параметр this
.
Со страницы man
:
int pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine) (void *),
void *arg);
Точка входа потока - void* (*)(void*)
.Ваша функция Base::action
имеет тип void* (Base::*)()
.Часть Base::
этого уродливого объявления типа обозначает тип this
.Расхождение типов является причиной того, что компилятор не примет ваш код.
Есть две вещи, которые нам нужно исправить, чтобы эта работа работала.Мы не можем использовать функцию-член, потому что указатели на функции-члены не привязывают this
к экземпляру.Нам также нужен один параметр типа void*
.К счастью, эти два исправления идут рука об руку, потому что решение состоит в том, чтобы явно передать this
самим.
class Base {
public:
virtual void* action() = 0;
protected:
pthread_t tid;
friend void* do_action(void* arg) {
return static_cast<Base*>(arg)->action();
}
};
class Derived : public Base {
public:
Derived() {
// This should be moved out of the constructor because this
// may (will?) be accessed before the constructor has finished.
// Because action is virtual, you can move this to a new member
// function of Base. This also means tid can be private.
pthread_create(&tid, NULL, &do_action, this);
}
virtual void* action();
};
Edit: Woops, если tid
равно protected
или private
, тогда do_action
должно быть friend
.