By "extending", I guess I can't change a postfix to a prefix, or its
precedence?
Right. And you cannot introduce new operators, either. (Say a
@ operator.) Basically, the compiler builds (or at least,
should be able to build) an expression tree without looking at
the types of the data. Only once it has the expression tree
does it look at the types, and map the operators onto either a
built-in operator or a user defined operator.
Can I change a member function to a non-member and vice
versa?
In general, no. Most operators, however, can be defined as
either one or the other.
Can I change a unary operator to a binary or a binary to a
unary?
No. On the other hand, C++ has a number of operator tokens
which can represent two different operators, one binary and one
unary. The choice of which is made *before* the compiler
evaluates whether to use a user defined operator or a built-in,
however.
Also, when ">>" and "<<" are used by iostream, are then member
operators of iostream or non-member functions?
Either (or in this case, both). >> and << are binary operators;
there are two ways of overloading a binary operator (with a few
exceptions): as a member function taking a single argument (with
the object the member function is called on as the first
argument to the operator, and the function argument as the
second), or as a free function taking two arguments.
The important thing to keep in mind here is that when the
compiler sees << or >>, it doesn't immediately consider
overloading of any sort. It just notes that it has a binary
operator of such and such precedance and binding, and continues
building the expression tree. Only when it has finished, and is
actually generating code, will it look at the possible
overloads, and do overload resolution over the set of built-in
operators, member function redefines, and free function
redefines.
I see, it's the standard, though it doesn't look very obvious why
standard says it.
True, but not for the reasons you seem to be saying. A priori,
looking at it, one would expect -> to be a binary operator.
It's not treaded as such, however, but as a unary operator. And
as a unary operator, if it is defined as a member function, the
operand is the object it is called on.
There aren't many examples of postfix unary operators to draw
on. (++ and -- are very special, as they can be either prefix
or postfix.) But this behavior is consistent with the idea that
a member function is called on an object, and that if the member
function is a user defined operator overload, the object the
function is called on is the first operand of the operator,
regardless of where the operand occurs relative to the operator.
When "->" is used with a pointer "p->b()" is
equivalent to (*p).b(). which doesn't show how we can use "->" with
user-defined class types.
This is true in general. For built in operators, a += b is the
equivalent of a = a + b, but there is no relationship if the
operators are defined by the user (unless the user decides to
create one---which is highly recommended).