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
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:
... jetzt kompiliert es.
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).
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.
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.
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
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.