Was kann ich anstelle des Pfeiloperators `->` verwenden?

112

Wofür ist der Pfeiloperator ( ->) ein Synonym?

PA
quelle

Antworten:

148

Die folgenden zwei Ausdrücke sind äquivalent:

a->b

(*a).b

(vorbehaltlich einer Überlastung des Bedieners, wie Konrad erwähnt, aber das ist ungewöhnlich).

Greg Hewgill
quelle
9
Überlastungsprobleme sind viel weniger ungewöhnlich als Sie denken. Vor nicht ->allzu langer Zeit hatten STL-Implementierer für einige Iteratortypen keinen überladenen Operator, sodass Sie ihn verwenden mussten *.. Viele Bibliotheken definieren sie inkonsistent. Wird wirklich nervig, wenn Sie mit Vorlagen arbeiten und den genauen Typ nicht kennen.
Konrad Rudolph
1
Sie können auch a[0].banstelle von tun (*a).b. Aber es wäre nicht so richtig strukturiert.
Sellorio
2
Junge, nach vielen Jahren der C # -Programmierung ist die Rückkehr zu C ++ nicht nur kognitiv anstrengend, die C ++ - Syntax ist einfach hässlich und eklig. Ich möchte nach dem Gebrauch duschen. In c und c ++ geschriebene Programme fördern nur schlechte Programmierung. Apple, Pre-Unix, hatte Mühe, die Sprache so hübsch wie Pascal zu machen.
ATL_DEV
@ATL_DEV Ich würde argumentieren, dass viele der hässlichen Dinge nicht mehr als idiomatisch angesehen werden, aber das bedeutet leider nicht, dass Sie es sich leisten können, als praktizierender C ++ - Programmierer nicht damit vertraut zu sein. Auch der syntaktisch schöne Pfad ist oft nicht der semantisch schöne Pfad, aber das wurde auch besser und nicht schlechter. Aber andererseits habe ich C ++ Stockholm-Syndrom.
Tim Seguine
@ TimSeguine Wenn Sie jemals hübschen Code sehen möchten, lesen Sie die Dokumentation zum Macintosh. Ich denke, sie haben CamelCase erfunden. Sehr beschreibende Variablennamen und elegant formatierter Code. Sie haben es geschafft, ihren späteren C-Code fast so großartig zu machen wie ihren früheren Pascal-Code.
ATL_DEV
70

a->bist in der Regel ein Synonym für (*a).b. Die Klammern hier sind aufgrund der Bindungsstärke der Operatoren erforderlich *und .: *a.bwürden nicht funktionieren, da die .Bindung stärker ist und zuerst ausgeführt wird. Dies entspricht also*(a.b) .

Hüten Sie sich vor Überlastung, aber: Da beide ->und *überlastet werden können, kann ihre Bedeutung drastisch unterscheiden.

Konrad Rudolph
quelle
1
Mit binding strengthSie meinen Operator Vorrang? Wenn nicht, was ist der Unterschied zwischen den beiden?
Vishnuprasanth
1
@Vizkrig Ja, die beiden Begriffe werden synonym verwendet (obwohl "Operator-Vorrang" zumindest in den letzten Jahren viel häufiger zu sein scheint).
Konrad Rudolph
45

Die C ++ - Sprache definiert den Pfeiloperator ( ->) als Synonym für die Dereferenzierung eines Zeigers und verwendet dann die. -operator für diese Adresse.

Beispielsweise:

Wenn Sie ein Objekt anObjectund einen Zeiger haben , aPointer:

SomeClass anObject = new SomeClass();
SomeClass *aPointer = &anObject;

Um eine der Objektmethoden verwenden zu können, dereferenzieren Sie den Zeiger und führen einen Methodenaufruf für diese Adresse durch:

(*aPointer).method();

Was mit dem Pfeiloperator geschrieben werden könnte:

aPointer->method();

Der Hauptgrund für das Vorhandensein des Pfeiloperators besteht darin, dass er die Eingabe einer sehr häufigen Aufgabe verkürzt und die Klammern um die Dereferenzierung des Zeigers leicht vergisst. Wenn Sie die Klammern vergessen haben, bindet der.-Operator stärker als der * -Operator und lässt unser Beispiel wie folgt ausführen:

*(aPointer.method()); // Not our intention!

Einige der anderen Antworten haben auch erwähnt, dass C ++ - Operatoren überladen sein können und dass dies nicht so häufig vorkommt.

PA
quelle
8
new SomeClass()Gibt einen Zeiger ( SomeClass *) zurück, nicht das SomeClassObjekt. Und Sie beginnen mit der Deklaration anObjectund aPointerverwenden sie panschließend.
Musiphil
Insgesamt ist diese Erklärung theoretisch sehr zutreffend, nur die Veränderung von Objekten macht sie ein wenig verworren. Aber der Prozess ist besser beschrieben
Code Man
17

In C ++ 0x erhält der Operator eine zweite Bedeutung, die den Rückgabetyp einer Funktion oder eines Lambda-Ausdrucks angibt

auto f() -> int; // "->" means "returns ..."
Johannes Schaub - litb
quelle
1
Technisch gesehen ist es dort kein "Operator" mehr, oder?
Martin Ba
6
@Martin Die meisten Leute verwenden das Wort "Operator" für viele Dinge, die nicht direkt für die Berechnung von Werten verwendet werden. Wie für "::" ("Bereichsoperator"). Ich weiß nicht genau, wie der Standpunkt des Standards dazu lautet. In einem abstrakten Sinne könnte man "->" als einen funktionalen Operator betrachten, der eine Folge von Typen (Parametern) einem Rückgabetyp zuordnet, wie den haskell-Operator, der ebenfalls "->" geschrieben ist.
Johannes Schaub - Litb
6
Ich gebe auf! :-P
Martin Ba
2
@ JohannesSchaub-litb: ::ist eigentlich ein Operator wie .oder ->und wird im Standard als "Scope Resolution Operator" bezeichnet.
Musiphil
13

Ich lese es meistens von rechts nach links und rufe "in" an.

foo->bar->baz = qux->croak

wird:

"baz in bar in foo wird in qux krächzen."

Tetha
quelle
1

-> wird beim Zugriff auf Daten verwendet, auf die Sie einen Zeiger haben.

Sie können beispielsweise einen Zeiger ptr auf eine Variable vom Typ int intVar wie folgt erstellen:

int* prt = &intVar;

Sie können dann eine Funktion wie foo nur verwenden, indem Sie diesen Zeiger dereferenzieren, um die Funktion für die Variable aufzurufen, auf die der Zeiger zeigt, und nicht für den numerischen Wert des Speicherorts dieser Variablen:

(*ptr).foo();

Ohne die Klammern hier würde der Compiler dies als *(ptr.foo())Folge der Operatorpriorität verstehen, die nicht das ist, was wir wollen.

Dies ist eigentlich genau das gleiche wie Tippen

ptr->foo();

Als ->Dereferenzierung dieses Zeigers ruft er so die Funktion foo()für die Variable auf, auf die der Zeiger für uns zeigt.

Ebenso können wir verwenden, ->um auf ein Mitglied einer Klasse zuzugreifen oder es festzulegen:

myClass* ptr = &myClassMember;
ptr->myClassVar = 2; 
Tryb Ghost
quelle
0

Mit -> können Sie eine Funktion definieren.

auto fun() -> int
{
return 100;
}

Es ist kein Lambda. Es ist wirklich eine Funktion. "->" gibt den Rückgabetyp der Funktion an.

Zhang
quelle