2010-11-24 13 views
32

Gibt es einen generellen Unterschied zwischenPointer Dereferenzierungsoperator ((*) vs ->)

tun
(*ptr).method() 

vs

ptr->method() 

Ich sah diese Frage in einem Kommentar zu einer anderen Frage und dachte, ich würde frag es hier. Obwohl ich mich gerade daran erinnert habe, dass so ziemlich jeder Operator in C++ überlastet werden kann, denke ich, dass die Antwort davon abhängen wird. Aber gibt es im Allgemeinen einen Unterschied zwischen dem einen und dem anderen?

+0

BTW, war der Kommentar von dieser Frage: http://stackoverflow.com/questions/4263640/find-mapped-value-of-map/4263652#4263652 :) – wrongusername

Antwort

56

Wie "jamesdlin" bereits erwähnt, können die * und -> Operatoren für Klassenarten überladen werden. Die beiden Ausdrücke (*ptr).method() und ptr->method() können unterschiedliche Auswirkungen haben.

Für die integrierten Operatoren sind die beiden Ausdrücke jedoch äquivalent.

Der -> Operator ist bequemer, wenn Sie eine Kette von Zeigern folgende sind, weil . höhere Priorität hat als *, so viele ungrokkable Klammern erfordern.

Bedenken Sie:

pBook->author->snailMail->zip 

gegen

(*(*(*pBook).author).snailMail).zip 
0

Sie sind Synonyme. Letzteres ist eine Kurzform für das erstgenannte.

4

Aber im Allgemeinen, gibt es einen Unterschied zwischen dem einen und dem anderen?

Nein! (Es sei denn -> und * überlastet sind explizit verschiedene Funktionen auszuführen)

ptr->method() und (*ptr).method() äquivalent sind.

+0

Diese Operatoren können für Klassen und dann überladen werden Die beiden Ausdrücke können unterschiedliche Auswirkungen haben. Das Nein!" ist richtig für die eingebauten Operatoren. Prost, –

+0

@Alf: Hinzugefügt 'außer' Teil. :) –

9

Ja. ptr->method() ist zwei Zeichen kürzer als (*ptr).method().

Es ist auch hübscher.

12

Für rohe Zeigerarten sind sie das Äquivalent.

Und ja, für allgemeine Typen, ist die Antwort in der Tat "es kommt darauf an", wie Klassen operator* und operator-> überladen können, unterschiedliche Verhaltensweisen zu haben.

+38

Wenn eine Klasse das tut, sind Sie natürlich berechtigt, den Autor ins Gesicht zu schlagen ... Hart. – jalf

1

Die Sequenz -> dient als visueller Indikator, dass sie auf etwas zeigt. Beide Operatoren führen genau die gleiche Abfolge von Operationen durch.

8

C++ Standard-5.2.5/3:

Wenn die E1-Typ hat „Zeiger auf Klasse X“, dann wird der Ausdruck E1-> E2 ist in die entsprechende Form umgewandelt (* (E1)) E2;

Bei Nicht-Zeigerwerten könnten Operatoren überlastet sein.

2

Leider diesen Beitrag zu graben, aber auch wenn die Ausdrücke in der OP für Rohzeiger Typen äquivalent sind, ich glaube, es gibt mindestens einen wichtig ist Unterschied in C++ zu erwähnen, zusätzlich zu allem, was gesagt wurde:

Von Wikipedia (http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#cite_note-arrowptr-6):

Der Rückgabetyp des Operators ->() muss ein Typ sein, für den die Operation -> angewendet werden kann, z. B. ein Zeigertyp. Wenn x vom Typ C ist, wobei C den Operator ->() überlädt, wird x-> y auf x.operator ->() -> y erweitert.

Dies bedeutet, dass -> wird erwartet, eine dereferenceable Typ zurückzukehren, während * erwartet wird zurück ein dereferenced Typ und daher diese „Chaining“ gilt für -> nur.

+0

Ich sehe Ihren Standpunkt nicht? Die unterschiedlichen Rückgabetypen sind eine Grundwahrheit, die der Syntax/Platzierung der beiden Operatoren innewohnt. Wie Alf gezeigt hat, hindert Sie das nicht daran, genau die gleichen Dinge mit '* (ptr)' zu tun, wenn Sie genug Mühe haben, genug Sterne und Klammern einzugeben. (Als konzeptioneller Operator ist '->' ein Geschenk; ich wünschte nur, es hätte nicht zwei Zeichen verwendet.) –

+1

Mein Punkt ist, dass ihre Implementierung (und Verwendung) etwas, aber wichtig anders ist; Insbesondere mag es nicht intuitiv sein, dass '->' einen "Zeiger" und keine "Referenz" zurückgibt, und dieser kleine Unterschied ist der fundamentale Grund, warum man leicht verkettet werden kann und nicht der andere (Verkettung kann nur passieren, wenn Eingabe und Ausgabe verhalten sich auf die gleiche Weise). Einige Leute (wie Sie es scheinen) bevorzugen sachliche Erklärungen in Bezug auf den praktischen Nutzungsunterschied, ich bevorzuge nur grundlegende Gründe (aus denen ich sachliche Unterschiede selbst ableiten kann). – Sheljohn

+0

Ich sorta, was du meinst, aber vielleicht ist es für verschiedene Leute unterschiedlich intuitiv: wenn man bedenkt, dass '->' einen Operator überschreibt, der von Zeigern stammt, habe ich immer erwartet, dass er mit einem Zeiger (nicht Referenz) -Typ Objekt arbeitet Das ist das Fundamentale. Aber ich bin sicher, dass ich durch einfachere Dinge verwirrt wurde, also was auch immer jedem hilft, es zu verstehen, ist alles gut. –