2010-11-15 19 views
13

Ich lese etwas Material über Funktionszeiger in C++, und stoße auf eine Funktionsdefinition, die ich nicht verstehe.
Standard-Funktionsdefinition hat die Form:
Eine Frage über Funktionsdefinition in C++

type name (param...) 

Aber die folgende Definition scheint mir ein wenig seltsam. Kann mir das jemand erklären? Danke.

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


Hinweis: Plus und Minus sind zwei Funktionen mit param (float, float) und einen Schwimmer zurück.

+0

sein, es kann besser sein 'wenn andere (opCode == 'zu überprüfen -')' in futu einige Nachtschichten zu vermeiden brennen re – Chubsdad

+0

Thema erzählt nicht viel über Ihre Frage .. Es sollte. – mih

Antwort

10

Die Regel haarige Erklärungen zum Lesen ist mit der linken Kennung zu starten und Ihren Weg aus arbeiten, daran erinnern, dass () und [] bind vor * (dh *a[] ist ein Array von Zeigern, (*a)[] ein Zeiger auf ein Feld ist, ist eine Funktion *f() einen Zeiger zurückkehrt, und (*f)() ist ein Zeiger auf eine Funktion):

 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 

wenn also opCode gleich ‚+‘, GetPtr1 Willen r Um einen Zeiger auf die Funktion Plus zu setzen, und wenn es '-' ist, wird ein Zeiger auf die Funktion Minus zurückgegeben.

C- und C++ - Deklarationssyntax ist expressionszentriert (ähnlich wie Bjarne gerne etwas anderes vorgeben würde); Die Form der Deklaration sollte mit der Form des Ausdrucks übereinstimmen, wie er im Code verwendet werden würde.

Wenn wir eine Funktion f haben, die einen Zeiger auf int zurück, und wir wollen den Wert für den Zugriff auf die verwiesen wird, führen wir die Funktion und dereferenzieren das Ergebnis:

x = *f(); 

Der Typ des Ausdruck*f() ist int, so die Erklärung/Definition für die Funktion ist

int *f() { ... } 

Nehmen wir nun an haben wir eine Funktion f1, die einen Zeiger auf die oben definierte Funktion f zurückgibt, und wir möchten auf diesen Ganzzahlwert zugreifen, indem wir f1 aufrufen. Wir müssen f1 nennen, derefence das Ergebnis (die die Funktion f ist), und ausführen und dann dereferenziert dass Ergebnis (da f einen Zeiger zurückgibt):

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

Der Typ des Ausdruck*(*f1())() ist int, so dass die decaration/Definition für f1 Bedürfnisse

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

schätzen die eingehende Erklärung der Rechts-Links-Regel +1 – Chubsdad

+0

+1 für die Erweiterung eines Funktionszeigers in seine Komponenten. Wird Menschen helfen, zum ersten Mal auf sie zu stoßen. –

3

Es ist eine Funktion, die eine const char nimmt und einen Zeiger auf eine Funktion zurückgibt, die float, float nimmt und eine float zurückgibt.

+0

... und return float –

+0

@Paul: Richtig, danke. –

16

GetPtr1 ist eine Funktion, die ein Opcode-Zeichen übernimmt und einen Zeiger auf eine Funktion zurückgibt. Die Funktion, die zurückgegeben wird, benötigt zwei Gleitkommazahlen und gibt einen Gleitkommawert zurück.

Viele Male ist es einfacher zu lesen, wenn Sie so etwas tun:

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, Viel einfacher zu verwenden richtige typedefs, könnten Sie auch die 'C++ 0x' Version, etwas in der Form von:' typedef std :: function FloatOperationType; 'wenn mein Gedächtnis Serviert mich richtig. –

2

, die eine Funktion bedeutet, die ein Zeichen nimmt und gibt einen Zeiger auf eine Funktion, die einen Schwimmer zwei Schwimmer und kehrt nimmt.

5

Immer schön zu wissen über http://cdecl.org für solche Situationen. Beachten Sie, dass dies nur funktioniert, wenn Sie die Parameternamen entfernen. Dies ist, was Sie für float(*GetPtr1(const char))(float, float) erhalten:

erklären GetPtr1 als Funktion (const char) Zeiger Rückkehr (float, float) Rückkehr float

+0

Nice to oo. –

1

GetPtr1 zu funktionieren ist eine Funktion, die zwei Schwimmer als Eingabeparameter nimmt und gibt einen Zeiger auf eine Funktion, . Das ist viel mehr klar:

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


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