One interesting part of operator overloading that has not been mentioned above is the ability to overload the "conversion operators". You can override the conversion operators to allow your user-defined types to be converted to either built-in types or other user-defined types.

A member function Class::operator X(), where X is a type name, defines behaviour for a conversion of Class to X. Note that lack of return value - the type is mentioned as part of the function name, and cannot be repeated as the return type. Leave the return type blank.

Consider a String class -

class String {
  private:
    char* data;
  public:
    operator char*();

    ...
};

String::operator char*() {
  return data;
}

int main() {
  String s = "foobar";
  char* c = s; // allows implicit conversion
}
Use this technique sparingly, ambiguities with user-defined and built-in operators are likely to be quite common.