Whether an operator function is implemented as a member function or as a non-member function, the operator is still used the same way in expressions. So which is best?
When an operator function is implemented as a member function, the leftmost (or only) operand must be an object (or a reference to an object) of the operator’s class. If the left operand must be an object of a different class or a fundamental type, this operator function must be implemented as a non-member function (as we did in Section 10.5 when overloading <<
and >>
as the stream insertion and stream extraction operators, respectively). A non-member operator function can be made a friend
of a class if that function must access private
or protected
members of that class directly.
Operator member functions of a specific class are called (implicitly by the compiler) only when the left operand of a binary operator is specifically an object of that class, or when the single operand of a unary operator is an object of that class.
Another reason why you might choose a non-member function to overload an operator is to enable the operator to be commutative. For example, suppose we have
a fundamental type variable, number
, of type long
int
and
an object bigInteger
, of class HugeInteger
—a class in which integers may be arbitrarily large rather than being limited by the machine word size of the underlying hardware (class HugeInteger
is developed in the chapter exercises).
Both the expressions bigInteger
+
number
(the sum of a HugeInteger
and a long
int
) and number
+
bigInteger
(the sum of a long
int
and a HugeInteger
) can produce a temporary HugeInteger
containing the sum of the values. Thus, we require the addition operator to be commutative (exactly as it is with two fundamental-type operands).
The problem is that the class object must appear on the left of the addition operator if that operator is to be overloaded as a member function. So, we also overload the operator as a non-member function to allow the HugeInteger
to appear on the right of the addition. The operator+
function that deals with the HugeInteger
on the left can still be a member function. The non-member function can simply swap its arguments and call the member function. You also could define both overloads as non-member functions.