2010-11-15 3 views
13

Я читаю материал о указателе функции в C++ и сталкиваюсь с одним определением функции, которое я не понимаю.
Стандартного определения функции имеет вид:
Один вопрос о определении функции в C++

type name (param...) 

Но следующее определение кажется немного странным для меня. Может ли кто-нибудь объяснить это мне? Спасибо.

float (*GetPtr1(const char opCode)) (float, float)<br> 
{ 
    if(opCode == '+') 
     return &Plus; 
    else 
     return &Minus; // default if invalid operator was passed 
} 


Примечание: Плюс и минус две функции с парами (поплавком, поплавком) и вернуть поплавок.

+0

может быть лучше, чтобы проверить «еще если (опкод ==„-“)», чтобы избежать горения некоторые полуночное масло в грядущих событий re – Chubsdad

+0

Тема не говорит много о вашем вопросе .. Это должно быть. – mih

ответ

10

Правило для чтения волосатых декларации начать с крайней левой идентификатору и работать свой путь, помня, что () и [] связывают, прежде * (т.е. *a[] представляет собой массив указателей, (*a)[] является указателем на массив, *f() функция возвращает указатель, и (*f)() является указателем на функцию):

 GetPtr1          -- GetPtr1 
     GetPtr1(    )     -- is a function 
     GetPtr1(   opCode)     -- taking a single parameter named opCode 
     GetPtr1(const char opCode)     -- of type const char 
     *GetPtr1(const char opCode)     -- and returning a pointer 
     (*GetPtr1(const char opCode)) (   ) -- to a function 
     (*GetPtr1(const char opCode)) (float, float) -- taking two parameters of type float 
float (*GetPtr1(const char opCode)) (float, float) -- and returning float 

Таким образом, если opCode равно «+», GetPtr1 воли г eturn указатель на функцию Plus, и если это '-', он вернет указатель на функцию Minus.

Синтаксис объявления C и C++ является ориентированным на выражение (так как Бьярне хотел бы притвориться иначе); форма объявления должна соответствовать форме выражения, так как она будет использоваться в коде.

Если мы имеем функцию f, которая возвращает указатель на int и мы хотим получить доступ к значению на который указывает на, мы выполняем функцию и разыменования результат:

x = *f(); 

Типом выражения*f() является int, поэтому объявление/определение функции является

int *f() { ... } 

Теперь предположим, что мы имеем функцию f1, который возвращает указатель на указанную выше функцию f, и мы хотим получить это целочисленное значение, вызвав f1. Нам нужно вызвать f1, derefence результата (который является функцией f), и выполнить его, а затем разыменование что результата (так как f возвращает указатель):

x = *(*f1())(); // *f1() == f, so (*f1())() == f() and *(*f1())() == *f() 

Типом выражения*(*f1())() является int, поэтому decaration/определение f1 потребности быть

int *(*f1())() { return f; } 
+0

оцените углубленное объяснение правого-левого правила +1 – Chubsdad

+0

+1 для расширения функции указателя на его компоненты. Поможет людям впервые встретить их. –

3

Это функция, которая принимает const char и возвращает указатель на функцию, которая принимает float, float и возвращает float.

+0

... и возвращает float –

+0

@Paul: Правильно, спасибо. –

16

GetPtr1 - это функция, которая принимает символ opcode и возвращает указатель на функцию. Возвращаемая функция принимает два поплавка и возвращает float.

Много раз легче читать, если вы делаете что-то вроде этого:

typedef float (*FloatOperationFuncPtr) (float, float); 

FloatOperationFuncPtr GetPtr1(const char opCode) 
{ 
    if(opCode == '+') 
     return &Plus; 
    else 
     return &Minus; // default if invalid operator was passed 
} 
+1

+1, гораздо проще использовать правильные typedefs, вы также можете добавить версию 'C++ 0x', что-то вроде строк:' typedef std :: function FloatOperationType; 'если моя память служит мне правильным. –

2

Это означает, что функция, которая принимает символ и возвращает указатель на функцию, которая принимает два поплавка и возвращает число с плавающей точкой.

5

Всегда приятно знать о http://cdecl.org для таких ситуаций. Имейте в виду, что он работает только при удалении имен параметров. Это то, что вы получите за float(*GetPtr1(const char))(float, float):

объявить GetPtr1 в качестве функции (const char) возвращающего указатель функционировать (float, float) возвращение float

+0

Nifty t o o l. –

1

GetPtr1 это функция, которая принимает два поплавка в качестве входных параметров и возвращает указатель на функцию , Это намного более ясно:

typedef float(*Func)(float, float); 


Func GetPtr1(const char opCode) 
{ 
    if(opCode == '+') 
     return &Plus; 
    else 
     return &Minus; // default if invalid operator was passed 
} 
Смежные вопросы