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).