2016-03-15 4 views
0

Я bamboozled по указателям функций.Bamboozled указателями функции как аргументы другой функции внутри класса

Вот пример кода:

#include <iostream> 

class test 
{ 

    inline 
    void output_plumber_1(int* const arg_out, const int* const arg_in) 
    { 
     *arg_out = -*arg_in; 
    } 

    inline 
    void input_plumber_1(int* const arg_out, const int* const arg_in) 
    { 
     *arg_out = 2 * (*arg_in); 
    } 

    inline 
    void member_func(void (test::*output_plumber)(int* const arg_out, const int* const arg_in), 
        void (test::*input_plumber)(int* const arg_out, const int* const arg_in), 
        int arg) 
    { 

     int arg_copy; 
     (*input_plumber)(&arg_copy, &arg); 

     arg_copy = arg_copy + 1; 

     int arg_out; 
     (*output_plumber)(&arg_out, &arg_copy); 

     std::cout << arg_out << std::endl; 

    } 

public: 

    void execute(int arg) 
    { 
     void (test::*output_plumber)(int* const arg_out, const int* const arg_in) = &test::output_plumber_1; 
     void (test::*input_plumber)(int* const arg_out, const int* const arg_in) = &test::input_plumber_1; 

     member_func(output_plumber, input_plumber, arg); 
    } 


}; 


int main() 
{ 

    test mytest; 
    mytest.execute(1); 

    return 0; 

} 

Что это предполагается делать?

Это довольно скудный пример, но по существу у меня есть программа с классом с функцией-членом, которая работает с некоторыми входными данными. Перед выполнением операции и после выполнения операции данные должны быть поданы в набор входных и выходных функций «сантехник», которые изменяют данные при подготовке к «операции» и «делают что-то для этого, чтобы исправить для первоначальной подготовки «после» операции была проведена ».

Такая вещь возникла в моей программе, так как я работаю с алгоритмами, которые работают с парами данных (x, y), которые работают только при x> y. (Bizarre? Но так оно и есть.)

Что такое проблема?

Предположительно многочисленны, однако непосредственный вывод компилятора заключается в следующем:

main.cpp: In member function ‘void test::member_func(void (test::*)(int*, const int*), void (test::*)(int*, const int*), int)’: 
main.cpp:27:11: error: invalid use of unary ‘*’ on pointer to member 
     (*input_plumber)(&arg_copy, &arg); 
     ^
main.cpp:32:11: error: invalid use of unary ‘*’ on pointer to member 
     (*output_plumber)(&arg_out, &arg_copy); 
+0

Возникает вопрос: «Что делает этот co de do "или" почему этот код не компилируется "? –

+0

@JamesRoot Почему он не компилируется - я сам написал код, я знаю, что, по-моему, хочу, чтобы он это делал, это просто не синтаксически правильно – user3728501

+0

Если функции водопроводчика фактически не используют 'this', было бы лучше сделать их нечленами. Рассмотрим, что 'member_func' принимает' std :: function ', что является гораздо более общим. –

ответ

3

В этом:

void (test::*output_plumber)(int* const arg_out, const int* const arg_in) 

является указателем на функцию члена test, которая принимает два аргумента и возвращает void. Указатель на член просто указывает на заданную членную переменную или функцию, но не имеет никакого смысла вне контекста класса. Таким образом, вы не можете назвать один без экземпляра.

Два позволили синтаксисы:

(obj.*ptr)(args...) 
(p_obj->*ptr)(args...) 

в зависимости от того, или нет экземпляра является указателем. Таким образом, правильный синтаксис для вызова ваших указателей будет:

(this->*input_plumber)(&arg_copy, &arg); 
(this->*output_plumber)(&arg_out, &arg_copy); 

и правильный способ вызова вашей функция будет:

test_obj.member_func(&test::output_plumber_1, // <-- pointer to member 
    &test::input_plumber_1,     // <-- pointer to member 
    0); 
1
void (test::*input_plumber)(int* const arg_out, const int* const arg_in), 

Исходя из вашего вопроса, то кажется, что вы считаете, что выше указано параметр, который является указателем на функцию.

Ну, вышесказанное не является указателем на функцию. Это указатель метода класса. Это не то же самое, что указатель на функцию.

Вы не можете вызвать input водопроводчика, как если бы это был указатель функции:

(*input_plumber)(&arg_copy, &arg); 

Вы не можете это сделать, потому что это не указатель на функцию. Я упоминал, что это не указатель на функцию, а указатель метода класса? Да, я думаю, что да.

Чтобы вызвать указатель метода, предположив, что это то, что вы хотите сделать, вы должны найти экземпляр класса, метод которого вы хотите вызвать, с помощью указателя метода.

Asusming, что вы хотите, чтобы вызвать метод this «S:

(this->*input_plumber)(&arg_copy, &arg); 

Теперь, если у вас какой-то другой указатель test, лежащих вокруг, например:

test *some_ptr_to_test; 

Вы бы ссылаться, что Указатель метода объекта аналогичным образом:

(test->*input_plumber)(&arg_copy, &arg); 
+0

Они называются «указателями функций-членов». В отличие от C#, Java, Python и т. Д. В C++ нет конкретного понятия «метод». –

+0

'test -> *' должен быть 'some_ptr_to_test -> *' –

Смежные вопросы