What is the difference between the dot (.) operator and -> in C++?
14 Answers
foo->bar()
is the same as (*foo).bar()
.
The parenthesizes above are necessary because of the binding strength of the *
and .
operators.
*foo.bar()
wouldn't work because Dot (.
) operator is evaluated first (see operator precedence)
The Dot (.
) operator can't be overloaded, arrow (->
) operator can be overloaded.
The Dot (.
) operator can't be applied to pointers.
Also see: What is the arrow operator (->) synonym for in C++?

- 48,814
- 22
- 151
- 184
-
5Note that this is only for raw pointers. For class types that overload the operator, it has some other interesting properties... – David Rodríguez - dribeas Jul 17 '12 at 18:19
-
doesn't it bother that -> is a drill down operator, and thus if overloaded it is not equivalent to member of the derefenced object (*boo).foo ? as if boo->foo may be overloaded to return an intermediate proxy object which has a foo member different from that in the originating class. Wouldn't that assert( (*boo).foo == boo->foo ) fail. It is true that one should be cautious as the c++ elves may be lurking in the dark. – g24l Jan 19 '15 at 18:17
For a pointer, we could just use
*pointervariable.foo
But the .
operator has greater precedence than the *
operator, so .
is evaluated first. So we need to force this with parenthesis:
(*pointervariable).foo
But typing the ()'s all the time is hard, so they developed ->
as a shortcut to say the same thing. If you are accessing a property of an object or object reference, use .
If you are accessing a property of an object through a pointer, use ->

- 10,056
- 3
- 28
- 32

- 40,133
- 25
- 115
- 157
Dot operator can't be overloaded, arrow operator can be overloaded. Arrow operator is generally meant to be applied to pointers (or objects that behave like pointers, like smart pointers). Dot operator can't be applied to pointers.
EDIT
When applied to pointer arrow operator is equivalent to applying dot operator to pointee e.g. ptr->field
is equivalent to (*ptr).field
.

- 2,745
- 2
- 24
- 38

- 12,283
- 6
- 56
- 83
The arrow operator is like dot, except it dereferences a pointer first. foo.bar()
calls method bar()
on object foo
, foo->bar
calls method bar
on the object pointed to by pointer foo
.

- 4,853
- 29
- 30
-
1
-
@juanchopanza If `foo` is not a pointer and it is of type `MyType`, you will get a compilation exception: `base operand of '->' has non-pointer type 'MyType'`. – logi-kal Aug 31 '18 at 09:43
-
-
@juanchopanza But this is a generic question about how "the dot (.) operator and -> in C++" work, not about operators overloading. – logi-kal Sep 01 '18 at 11:17
-
@horcrux How those operators work in C++ has to take into account operator overloading. Without that, the picture is quite incomplete. – juanchopanza Sep 01 '18 at 15:35
The .
operator is for direct member access.
object.Field
The arrow dereferences a pointer so you can access the object/memory it is pointing to
pClass->Field

- 14,226
- 4
- 44
- 89

- 35,298
- 14
- 114
- 172
pSomething->someMember
is equivalent to
(*pSomething).someMember

- 48,814
- 22
- 151
- 184

- 23,169
- 18
- 105
- 180
Use ->
when you have a pointer.
Use .
when you have structure (class).
When you want to point attribute that belongs to structure use .
:
structure.attribute
When you want to point to an attribute that has reference to memory by pointer use ->
:
pointer->method;
or same as:
(*pointer).method

- 7,115
- 18
- 83
- 125
The target. dot works on objects; arrow works on pointers to objects.
std::string str("foo");
std::string * pstr = new std::string("foo");
str.size ();
pstr->size ();

- 11,767
- 6
- 38
- 39
Note that the -> operator cannot be used for certain things, for instance, accessing operator[].
#include <vector>
int main()
{
std::vector<int> iVec;
iVec.push_back(42);
std::vector<int>* iVecPtr = &iVec;
//int i = iVecPtr->[0]; // Does not compile
int i = (*iVecPtr)[0]; // Compiles.
}

- 959
- 7
- 12
-
6Clearly not. Because "foo->" does not mean "(*foo)". It means "(*foo).". It also can't be used for addition, subtraction... ;) – jmtd Aug 06 '09 at 13:21
-
I don't see how that's relevant. member[0] also doesn't mean anything, however syntactic sugar transforms it into member.operator[](0) if applicable. It's noteworthy that -> will not allow you to do what most people generally expect to be able to. – gparent Aug 06 '09 at 13:56
-
-
1I would imagine iVecPtr->operator[](0) would work, though. The point being that the syntactic sugar that you site turns [0] into .operator[](0); it does not turn .[0] into .operator[](0). – Domenic Aug 07 '09 at 01:18
It's simple, whenever you see
x->y
know it is the same as
(*x).y

- 39,555
- 5
- 63
- 78
-
3
-
3When you overload -> you should also overload * such that this relationship holds. To do otherwise will introduce all sorts of confusion anyway. – Logan Capaldo Aug 06 '09 at 13:39
-
if (*x).y equal to x->y , why cpp don't allow calling functors in the same way. for e.g. CPP gives error if we call functors like x->(a) but (*x)(a) will compile. There could be something more ...any idea. – Justin Mathew May 21 '23 at 21:50
The -> is simply syntactic sugar for a pointer dereference,
As others have said:
pointer->method();
is a simple method of saying:
(*pointer).method();
For more pointer fun, check out Binky, and his magic wand of dereferencing:

- 4,737
- 3
- 31
- 35
The simplest difference between the two is that "->" dereferences a pointer before it goes to look at that objects fields, function etc. whereas "." doesn't dereference first. Use "->" when you have a pointer to an object, and use "." when you're working with the actual instance of an object.
Another equivalent way of wrinting this might be to use the dereferencing "*" on the pointer first and then just use the ".". We skip middleman by using "->".
There are other differences, but the other answers have covered this extensively.
If you have a background in Java this might confuse you, since, in Java, everything is pointers. This means that there's no reason to have symbol that doesn't dereference your pointer first. In c++ however you gotta be a little more careful with remembering what is and what isn't a pointer, and it might be a good idea to label them with the prefix "p_" or simply "p".

- 21
- 1
The . (dot) operator is usually used to get a field / call a method from an instance of class (or a static field / method of a class).
p.myField, p.myMethod() - p instance of a class
The -> (arrow) operator is used to get a field / call a method from the content pointed by the class.
p->myField, p->myMethod() - p points to a class

- 17,449
- 12
- 49
- 59
The -> operator is used when we are working with a pointer and the dot is used otherwise. So if we have a struct class like:
struct class{ int num_students; int yr_grad; };
and we have an instance of a class* curr_class (class pointer), then to get access to number of students we would do
cout << curr_class->num_students << endl;
In case we had a simple class object , say class_2016, we would do
cout << class_2016.num_students << endl;
For the pointer to class the -> operator is equivalent to
(*obj).mem_var
Note: For a class, the way to access member functions of the class will also be the same way

- 8,096
- 3
- 21
- 38