2013-08-09 2 views
13

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

#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 
+0

Я всегда нахожу http://www.newty.de/fpt/index.html очень полезным. – arne

+2

Функции-члены не являются функциями. Вам нужен тип 'void (test :: *) (void *)' ... –

+1

Kerrek SB прав. Однако, если вы намереваетесь вызывать одного и того же члена для разных классов и экземпляров, вы должны думать о наследовании и виртуальных машинах ... –

ответ

19

Вы не можете бросить указатель на функцию 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(); 
} 
+1

void test :: call_cb_func() {(this -> * cb_func)(); Один НИКОГДА не хочет вызывать функцию указателем изнутри объекта. Таким образом, «это» в примере является совершенно бесполезным объяснением. Учитывая, что C++ - это, возможно, самый бесчеловечный синтаксис, отличный от hex, нельзя просто угадать, как вызвать функцию из объекта ANOTHER. –

2

В дополнение к ответу ОНП, вы можете также использовать function wrapper от C++ 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(); 
} 
Смежные вопросы