If we need type conversions on all parameters to a function including the one pointed to by the this
pointer, the function must be a nonmember.
Having classes support implicit type conversions is generally a bad idea. One good and common exception to the rule is when creating numerical types, for example, we want to allow implicit conversions from integers to userdefined rationals type:


We’d like to support arithmetic operation of multiplication, and one way is to declare it as a member function of Rational
:


This design is fine to multiply rationals with rationals:


However, for mixedmode operations, where Rational
s is multiplied with int
s, there will be a potential error:


This problem is clearer for analysis when we rewrite the last two examples in their equivalent functional form:


For the first statement:
the object oneHalf is an instance of a class that contains an operator*
taking a Rational
as its argument. Compilers know we’re passing an int
and that the function requires a Rational
, and they also know they can conjure up a suitable Rational
by implicit type conversion  calling the Rational
constructor with the int
we provided, so compilers will happily call that function as if it had been written like this:


Of course, compilers are allowed to do this implicit type conversion only because a nonexplicit constructor is involved. If we add keyword explicit
before the constructor above, neither of the two mixedtype multiplication statements would compile.
Now for the second statement:
it turns out that parameters are eligible for implicit type conversion only if they are listed in the parameter list. The implicit parameter pointed to by this
, which is also the obejct on which the member function is invoked, is never eligible for implicit conversions. Back to the second statement, int
type 2
does not have associated class containing a function operator*
taking a Rational
type object as its argument, nor is 2
listed in the parameter list for an implicit type conversion to Rational
. That is the cause of compilation failure.
In fact, when compilers fail to find a matching member function, they will also look for nonmember operator*
s (i.e., ones at namespace or global scope) that can be called like this:


And this is exactly what we want if we’d like to support mixedmode arithmetic: make opeartor*
a nonmember function, thus allowing compilers to perform implicit type conversions on all arguments:


Now comes anoter worry: should operator*
be made a friend of the Rational
class?
In this case, the answer is no, because operator*
can be implemented entirely through Rational
's public interface. This leads to an important observation:
The opposite of a member function is a nonmember function, not a frient function.
There’s some misunderstanding that if a function is related to a class and should not be a member (due, for example, to type conversions on all arguments), it should be a friend. This reasoning turns out to be flawed. The basic rule is to avoid friend functions whenever we can.
P.S.: This item contains the truth, but it is not the whole truth. When we cross the line from ObjectOriented C++ into Template C++ (item 1), and make
Rational
a class template instead of a class, refer to item 46 for some new issues to consider, new ways to solve them, and new design implications.