2010-10-01 4 views
2

Я еще не очень хорошо знаком с ними, но, возможно, кто-то может осветить этот пример.Использование указателей функций?

Представьте, что у меня есть класс CFoo, и у него будет функция для добавления обработчика и функции, которая является указателем на функцию.

Так что-то вроде этого:

class CFoo { 

int *pointedFunc(int a, int b) = 0; 

void setFunc(int *func(int a, int b)) 
{ 
    pointedFunc = func; 
} 
}; 

Учитывая вышеизложенное контекст, я хочу знать правильный способ сделать это. Я не думаю, что я сделал это правильно. Кроме того, как я мог бы позвонить в pointFunc?

Благодаря

+1

Не «a * function *, который является указателем на функцию», а «переменная-член * * (известная в OO как * поле *), которая является указателем на функцию». –

+0

Пожалуйста, избегайте указателей функций в коде C++. Определите интерфейс и создайте типы, реализующие этот интерфейс. Затем вы можете аккуратно хранить объекты, не прибегая к C hocks-pockus указателей на функции. –

+0

@Martin: Иногда интерфейс - это правильный подход, иногда шаблонные (и утиные) функторы, а иногда и указатели на функцию лучше. Для динамической компоновки необходимы указатели на функции. –

ответ

8

Прямо сейчас у вас есть функция-член, возвращающая int *, а не указатель на функцию, возвращающую int. Набор скобок исправит это.

int (*pointedFunc)(int a, int b); 

void setFunc(int (*pfunc)(int a, int b)) 
{ 
    pointedFunc = pfunc; 
} 

Кроме того, переменные члены инициализируются в конструкторе CTOR-инициализатора-лист, как

CFoo::CFoo() : pointedFunc(0) {} 

не как вы сделали. Ваш = 0 был на самом деле чистым-спецификатором (и он не будет работать, если функция-член не является виртуальной), когда вы исправляете проблему с указателем-возвратом-вызовом vs-указателем на функцию, вы обнаружите, что компилятор также жалуется на ваши попытайтесь инициализировать его.

Using a typedef as Graeme suggests - это самый простой и удобный способ отслеживания типов указателей функций.

+0

О, спасибо, я не знал, что это было только для виртуальных функций. – jmasterx

+0

Это не столько, что это только для виртуальных функций, так как это '= 0' означает что-то ** совершенно другое ** (cue Monty Python), когда оно появляется в как объявление, когда оно появляется в объявлении данных.Фактически, 'int (* emphasisFunc) (int a, int b) = 0;' было бы отлично в качестве локальной переменной, которая может быть инициализирована, но переменные-члены инициализируются в конструкторе, а не в объявлении. –

+0

В то время как вы, безусловно, правы в настройке самой функции = 0, являющейся чистым спецификатором, у меня создается впечатление, что вы можете установить указатель функции * на NULL без каких-либо проблем, которые, я считаю, были оригинальными намерениями. – Bryan

3

В вашем примере, pointedFunc функция член, возвращает int *. Чтобы сделать это указатель на функцию, вам нужно скобки вокруг pointedFunc, как:

int (*pointedFunc)(int a, int b); 

ЬурейеЕ может сделать его более ясным:

class CFoo { 
    CFoo() : pointedFunc(NULL) {} 
    typedef int (*funcType)(int, int); 
    funcType pointedFunc; 

    void setFunc(funcType f) { 
     pointedFunc = f; 
    } 
}; 

Для вызова функции, вы можете использовать либо pointedFunc(1, 2) или (*pointedFunc)(1, 2). Я использую последнее, чтобы дать понять, что вы проходите через указатель функции, но либо будет работать.

+2

Нет, это не нормально, прямо сейчас у него есть функция-член с именем 'aimFunc', а тип возврата -' int * '. –

+0

ладно спасибо, я думаю, мне не хватает уверенности в себе: p – jmasterx

+0

@Ben: Вы правы - спасибо за разъяснение. Я исправил свой ответ. –

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