37

Is there a general difference between doing

(*ptr).method()

vs

ptr->method()

I saw this question in a comment on another question and thought I would ask it here. Although I just remembered that pretty much every operator in C++ can be overloaded, so I guess the answer will depend. But in general, is there a difference between doing one versus the other?

Rakete1111
  • 47,013
  • 16
  • 123
  • 162
Falmarri
  • 47,727
  • 41
  • 151
  • 191
  • BTW, the comment was from this question: http://stackoverflow.com/questions/4263640/find-mapped-value-of-map/4263652#4263652 :) – wrongusername Nov 24 '10 at 05:42

8 Answers8

66

As "jamesdlin" already noted, the * and -> operators can be overloaded for class types.

And then the two expressions (*ptr).method() and ptr->method() can have different effect.

However, for the built-in operators the two expressions are equivalent.

The -> operator is more convenient when you're following a chain of pointers, because . has higher precedence than *, thus requiring a lot of ungrokkable parentheses.

Consider:

pBook->author->snailMail->zip

versus

(*(*(*pBook).author).snailMail).zip
Alex
  • 9,313
  • 1
  • 39
  • 44
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
13

For raw pointer types, they are the equivalent.

And yes, for general types, the answer is indeed "it depends", as classes might overload operator* and operator-> to have different behaviors.

jamesdlin
  • 81,374
  • 13
  • 159
  • 204
  • 44
    if a class does that, of course, you are authorized to punch the author in the face... Hard. – jalf Nov 24 '10 at 06:42
10

Yes. ptr->method() is two characters shorter than (*ptr).method().

It is also prettier.

wrongusername
  • 18,564
  • 40
  • 130
  • 214
8

C++ Standard 5.2.5/3:

If E1 has the type “pointer to class X,” then the expression E1->E2 is converted to the equivalent form (*(E1)).E2;

For non-pointer values operators could be overloaded.

Jakub Arnold
  • 85,596
  • 89
  • 230
  • 327
Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
5

But in general, is there a difference between doing one versus the other?

No! (unless -> and * are explicitly overloaded to perform different functions)

ptr->method() and (*ptr).method() are equivalent.

Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
2

Sorry to dig this post, but even though the expressions in the OP are equivalent for raw pointer types, I think there is at least one important difference to be mentioned in C++, in addition to everything that has been said:

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

The return type of operator->() must be a type for which the -> operation can be applied, such as a pointer type. If x is of type C where C overloads operator->(), x->y gets expanded to x.operator->()->y.

This implies that -> is expected to return a dereferenceable type, whereas * is expected to return a dereferenced type, and therefore this "chaining" applies to -> only.

Jonathan H
  • 7,591
  • 5
  • 47
  • 80
  • I don't see your point? The differing return types are a basic truism inherent in the syntax/placement of the two operators. As Alf has shown, this doesn't stop you being able to exactly do the same things with `*(ptr)` if you can be bothered typing enough asterisks and parentheses. (As a conceptual operator, `->` is a gift; I just wish it didn't use two characters.) – underscore_d Dec 23 '15 at 21:44
  • 1
    My point is that their implementation (and usage) are slightly but importantly different; in particular, it might not be intuitive that `->` should return a "pointer" and not a "reference", and this little difference is the fundamental reason why one can be chained easily and not the other (chaining can only happen if the input and output behave in the same way). Some people (like you it would seem) prefer factual explanations in terms of practical usage difference, I just prefer fundamental reasons (from which I can derive factual differences myself). – Jonathan H Dec 23 '15 at 23:59
  • I sorta see what you mean, but maybe it's differently intuitive for different people: given that `->` overrides an operator that originated in pointers, I only ever expected it to work on a pointer (not reference) type object, and to me _that_'s the fundamental. But I'm sure I've been confused by simpler things, so whatever helps each person understand it is all good. – underscore_d Dec 24 '15 at 09:46
  • @underscore_d Respectfully I think you might have missed my point again; it's not about what it works _on_ but rather about what it returns given what it was applied to. Of course, you would expect `->` and `*` to work on pointers because that's how it works in C. But the important part is that `->` is expected to return a type that is dereference_able_ (i.e. that behaves the same as what `->` was applied to in the first place), whereas `*` is expected to return a dereferenc_ed_ type (which breaks the chaining, and that's why you then need to use `.` before using `*` again). – Jonathan H Dec 24 '15 at 15:20
  • All I can say is to me, this difference is obvious from how these operators are used in normal types and spec'd for custom types. But that's just me; if your way of explaining it helps you or someone else understand it, great. – underscore_d Dec 24 '15 at 15:46
1

The -> sequence serves as a visual indicator that it is pointing to something. Both operators do the exact same sequence of operations.

AK.
  • 743
  • 7
  • 13
0

They are synonyms. The latter is a shorthand for the former.

Alex Budovski
  • 17,947
  • 6
  • 53
  • 58