Передача указателя на функцию члена класса в качестве параметра - программирование

Передача указателя на функцию члена класса в качестве параметра

Я написал небольшую программу, в которой я пытаюсь передать указатель на функцию-член класса для другой функции. Можете ли вы, пожалуйста, помочь мне и где я ошибаюсь.?

#include<iostream>
using namespace std;
class test{
public:
        typedef void (*callback_func_ptr)();
        callback_func_ptr cb_func;

        void get_pc();

        void set_cb_ptr(void * ptr);

        void call_cb_func();
};
void test::get_pc(){
         cout << "PC" << endl;
}
void test::set_cb_ptr( void *ptr){
        cb_func = (test::callback_func_ptr)ptr;
}
void test::call_cb_func(){
           cb_func();
}
int main(){
        test t1;
            t1.set_cb_ptr((void *)(&t1.get_pc));
        return 0;
}

Я получаю следующую ошибку, когда пытаюсь ее скомпилировать.

error C2276: '&' : illegal operation on bound member function expression
4b9b3361

Ответ 1

Вы не можете наложить указатель на void*.

Если вы хотите, чтобы указатель функции указывал на функцию-член, вы должны объявить тип как

ReturnType (ClassType::*)(ParameterTypes...)

Кроме того, вы не можете объявить указатель на функцию связанного члена, например

func_ptr p = &t1.get_pc // Error

Вместо этого вы должны получить адрес следующим образом:

func_ptr p = &test::get_pc // Ok, using class scope.

Наконец, когда вы делаете вызов указателя функции, указывающего на функцию-член, вы должны вызывать его с экземпляром класса, членом которого является функция. Например:

(this->*cb_func)(); // Call function via pointer to current instance.

Здесь приведен полный пример со всеми внесенными изменениями:

#include <iostream>

class test {
public:
    typedef void (test::*callback_func_ptr)();
    callback_func_ptr cb_func;
    void get_pc();
    void set_cb_ptr(callback_func_ptr ptr);
    void call_cb_func();
};

void test::get_pc() {
    std::cout << "PC" << std::endl;
}

void test::set_cb_ptr(callback_func_ptr ptr) {
    cb_func = ptr;
}

void test::call_cb_func() {
    (this->*cb_func)();
}

int main() {
    test t1;
    t1.set_cb_ptr(&test::get_pc);
    t1.call_cb_func();
}

Ответ 2

В дополнение к ответам Snps вы также можете использовать обертка функций из С++ 11 для хранения лямбда-функции:

#include <iostream>
#include <functional>

class test
{
  public:
   std::function<void ()> Func;
   void get_pc();
   void call_cb_func();
   void set_func(std::function<void ()> func);
};

void test::get_pc()
{
  std::cout << "PC" << std::endl;
}

void test::call_cb_func()
{
  Func();
}

void test::set_func(std::function<void ()> func)
{
  Func = func;
}

int main() {
  test t1;
  t1.set_func([&](){ t1.get_pc(); });
  t1.call_cb_func();
}