Note that both terms "overriding" and "overloading" are greatly misleading. The canonical ->
operator accesses the member of an object referenced through a pointer, that is X* x; x->foo;
is accessing something pointed to by x
which is of a pointer type (or to be more precise a raw pointer).
However, the operator->
that you can implement as a non-static member function in aggregate types (i.e. "classes") does something different. In X* x; x->foo;
, ->
would still be the canonical structure operator, which cannot be changed. However, in Y y; y->foo
, ->
would invoke the operator->
member function of Y
. This seemingly small distinction is crucial as one operator can only be applied to raw pointer types and the other can only be applied to non-pointer types.
This is typically used to allow types to behave syntactically as-if they were raw pointers (with some semantic differences), like in shared_ptr
et al. This could not be achieved without this language support as shared_ptr<X>
and X*
could not be used in the same fashion if there was no shared_ptr<X>::operator->
allowing to mimic the canonical ->
operator that is applicable to X*
(but not X
).