C ++ - Fragen zu Funktionszeigern

8

Ich habe den folgenden Code geschrieben:

%Vor%

Ich habe den obigen Code auf VS2008 ausgeführt und jeder Funktionsaufruf gibt '100' zurück. Hier ist die Frage:

Q1 & gt; Gibt es ein Problem im Code?

Q2 & gt; Es scheint, dass C ++ keinen Unterschied zwischen * pf und pf macht. Ist das richtig?

Danke

    
q0987 17.11.2010, 16:28
quelle

5 Antworten

8

C ++ macht tatsächlich einen Unterschied zwischen den Typen double() und double(*)() , aber der Unterschied ist subtil. Wenn Sie einen Funktionstyp als Argument an eine Funktion übergeben, wird der Funktionstyp automatisch zu einem Funktionszeiger degradiert. (Dies ist, wie ich vermute, ähnlich, wie ein Array-Typ zu einem Zeigertyp degradiert wird, wenn er als Funktionsargument übergeben wird.)

Ein Funktionstyp und ein Funktionszeiger sind jedoch immer noch verschiedene Typen, je nach C ++ Typsystem. Betrachten Sie den folgenden Fall:

%Vor%

Dies sollte nicht kompiliert werden, da Sie einen Funktionstyp nicht als automatische Variable deklarieren können. (Denken Sie daran, dass Funktionen in C ++ keine erstklassigen Objekte sind.) Daher ist die Deklaration F func; ungültig. Wenn wir jedoch unsere Funktion main so ändern, dass die Vorlage stattdessen mit einer Funktion -Zeiger instanziiert wird, etwa so:

%Vor%

... jetzt kompiliert es.

    
Charles Salvia 17.11.2010, 16:46
quelle
2

Die folgenden Funktionen sind identisch:

%Vor%

Die Dereferenzierung eines Funktionszeigers (wie in g gezeigt) entspricht dem Aufruf des Namens dieser Funktion.

  

Q2 & gt; Es scheint, dass C ++ nicht macht   Differenz zwischen * pf und pf. Ist das   richtig?

Es gibt einen Unterschied zwischen * pf und pf (als Variablen). Wenn pf eine Funktion ist, sind * pf und pf () identisch (Beachten Sie die Klammern).

    
Carlo del Mundo 17.11.2010 16:36
quelle
0

Bei den meisten modernen Compilern gibt es keinen Unterschied zwischen "(* Variable)". und "Variable- & gt;". Allerdings muss die verwendete Klasse überprüft werden, um festzustellen, ob sie den Dereferenzierungsoperator außer Kraft setzt.

Viele Programmierer verwenden typedef beim Definieren von Funktionszeigern, hauptsächlich um das Lesen zu erleichtern. Außerdem kann die Syntax double pf() anfällig für Lesbarkeitsfehler sein und kann mit der Ausführung einer Funktion in der Parameterzeile verwechselt werden.

    
Thomas Matthews 17.11.2010 16:37
quelle
0

Es gibt kein Problem oder Unterschied in dem von Ihnen geposteten Code. Wenn Sie jedoch Vorlagen schreiben, die Funktoren verwenden, sollten Sie die Syntax in g2 verwenden. Berücksichtigen Sie Folgendes:

%Vor%

Beachten Sie, dass Sie, wenn Sie den Dereferenzoperator vor functor setzen, das Dienstprogramm des von Ihnen geschriebenen Algorithmus auf Funktionszeiger beschränken. Wenn Sie dies jedoch nicht angeben, kann jemand einen STL-Funktor übergeben, z. B. etwas, das von std::bind2nd zurückgegeben wurde.

Daher würde ich insgesamt empfehlen, die zweite Syntax (ohne * ) zu verwenden, wo dies möglich ist.

    
Billy ONeal 17.11.2010 16:47
quelle
0

Betrachten Sie den folgenden Codeabschnitt

%Vor%

Auf der anderen Seite

%Vor%

Es gibt also eine implizite Umwandlung von einer Funktion zu einem Zeiger (der "Zerfall" genannt wird). Dadurch können Sie auch ***...***pf sagen - beliebig oft dereferenzieren - in jedem Schritt findet eine Funktion zur Zeigerumwandlung statt, die den Effekt der vorherigen Dereferenzierung rückgängig macht.

In den Funktionsparameterlisten sind T f() und T (*f)() gleichwertige Wege (außer der Schreibweise) zum Deklarieren eines Parameters

%Vor%

Eine Referenz verhindert diese Anpassung des Parametertyps

%Vor%

Dies ist genau das gleiche wie für deklarierte Array-Parameter: Parameter sind niemals Arrays, aber sie werden immer Zeiger sein, wenn sie als Arrays deklariert wurden.

    
Johannes Schaub - litb 19.11.2010 15:35
quelle

Tags und Links