They don't do the same thing. '.' is used to access a member of the object. When '->' is used on a raw pointer it is used to access a member of the object that the pointer is pointing to. '->' can also be defined for class types.
Here is an example where you can use both '.' and '->' but with different meanings.
Apparently there is some historical reason as to why there is both . and -> for member access - (at least that is what I read some time previously).
I myself could not understand why - ( because the compiler knows whether something is an object or a pointer and should be able to act accordingly
and so only one of them (lets say for argument sake the dot operaror) would
be needed).
I'll do a search and see if I can find that write up again.
The point is that the two operators do different things.
. simply accesses a member of an object
-> de-references the pointer and then accesses a member of the object being pointed to.
Having two separate operators removes ambiguity - it tells the compiler exactly what to do, and it tells anyone reading the code what the compiler is doing.
This is important, because it's possible to create classes which have pointer-like behaviour. These classes can use the standard syntax of pointers, by overloading the * and -> operators.
The classic example is a smart pointer object, as implemented in the Boost libraries and now incorporated into the C++11 standard. These are objects, and therefore have members, so it is necessary to use the . operator to access those members. However, they also behave like pointers, so they override the -> operator to make it possible to access members of the data they are pointing to.
Imagine if the object being pointed to by the smart pointer had a member with the same name as a member of the smart pointer object itself. How would the compiler know which one you meant, without the distinction between . and -> operators?
struct S {
int I;
};
int main()
{
S test;
S * pointerTest = &test;
/*
At this point:
test.I is equal to pointerTest->I
But you can see how test is S, and pointerTest is S*.
They are NOT the same thing, NOT the same type.
Also, as noted above,
pointerTest->I is equal to (*pointerTest)->I
*/
}
As far as I know, a compiler knows if it's an object or pointer to an object. And thus the compiler should be able to generate the correct code. I'm searching for an explanation why the C standard defined it this way.
The thing about smart pointer objects and overriding the -> operator makes me believe the distinction is necessary. I never used this but I'll look into this more.
1 2 3 4 5 6 7 8 9
class S {
int I;
};
void foo(S* bar)
{
bar->I = 10;
bar.I = 10; //In this case, the compiler could know what bar is and could generate the correct code
}