Как работают функциональные указатели? - PullRequest
8 голосов
/ 25 декабря 2010

Я задаю несколько конкретных вопросов.

  1. Как я могу инициализировать их в классе?
  2. Как передать функцию в качестве аргумента?
  3. Должны ли указатели функций объявляться и определяться в классе?

Для вопроса № 2 я имею в виду следующее:

void s(void) {
   //...
}

void f(function) { // what should I put as type to pass a function as an argument
   //...
}

f(s);

Ответы [ 4 ]

24 голосов
/ 25 декабря 2010

Чтобы определить указатель на функцию, используйте следующий синтаксис:

return_type (*ref_name) (type args, ...)

Итак, чтобы определить ссылку на функцию с именем "doSomething", которая возвращает int и принимает аргумент int, вы должны написать следующее:

int (*doSomething)(int number);

Затем вы можете присвоить ссылку фактической функции следующим образом:

int someFunction(int argument) {
   printf("%i", argument);
}

doSomething = &someFunction;

Как только это будет сделано, вы можете вызвать его напрямую:

doSomething(5); //prints 5

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

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

typedef int (*FunctionAcceptingAndReturningInt)(int argument);

Затем вы можете использовать этот вновь определенный тип в качестве типа аргумента для функции:

void invokeFunction(int func_argument, FunctionAcceptingAndReturningInt func) {
   int result = func(func_argument);
   printf("%i", result);
}

int timesFive(int arg) {
   return arg * 5;
}
invokeFunction(10, &timesFive); //prints 50
2 голосов
/ 25 декабря 2010

это не строгий ответ, но чтобы включить настраиваемый / назначаемый код в качестве члена класса, я бы упомянул использование класса / структуры с оператором (). Например:

struct mycode
{
    int k;

    mycode(int k_) : k(k_)
    {
    }

    int operator()(int x)
    {
     return x*k;
    }
};


class Foo
{
public : Foo(int k) : f(k) {}
public : mycode f;
};

Вы можете сделать:

Foo code(5);
std::cout << code.f(2) << std::endl;

будет напечатано '10', я все написал нормально.

1 голос
/ 25 декабря 2010

Вы должны объявить f таким образом:

void f(void (*x)())
{
  x();  // call the function that you pass as parameter (Ex. s()).
}

здесь - превосходное руководство по указателям на функции и обратным вызовам.

0 голосов
/ 25 декабря 2010

Чтобы ответить на 3-й вопрос, вам не нужно объявлять его в классе.Но чтобы не нарушать инкапсуляцию, я обычно предпочитаю указатели на функции-члены или функторы, которые снова являются членами классов.Приведенными выше примерами являются указатели на функции в стиле C, за исключением Luis G. Costantini R. Вы можете взглянуть на this для подхода с указателями на функции-члены.Указатели на функции в стиле C, как правило, рассматриваются, например, как механизмы обратного вызова, где есть код C, который вы получаете асинхронные сообщения.В таких случаях нет альтернатив, вместо объявления методов-обработчиков в глобальной области видимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...