Defining Operators as Friend Functions

To overload an operator using a non-member function, you define a function named operator+ that takes two arguments, as follows:

class Fraction

{

public:

Fraction( long num, long den );

Fraction operator+( const Fraction &second ) const;

Fraction operator+( long second ) const;

friend Fraction operator+( long first,

const Fraction &second );

// ...

};

// ...

Fraction operator+( long first, const Fraction &second )

{

return Fraction( second.numerator + first * second.denominator,

second.denominator );

}

With a function like this, an expression like this

a = 1234 + b; // Friend function called

is interpreted as follows:

a = operator+( 1234, b ); // Friend function called

Notice that the friend function requires two parameters while the member function requires only one. The + operator requires two operands. When operator+ is defined as a member function, the first operand is the object for which it is called and the second operand is the parameter. In contrast, when operator+ is defined as a friend function, both of the operands are parameters to the function.

You cannot define both a friend function and member function that define the same operator.

You can also use either a member function or a friend function to implement a unary operator. For example, suppose you want to implement the negation (-) operator. You could do it as a member function that takes no parameters:

inline Fraction Fraction::operator-() const

{

return Fraction( -numerator, denominator );

}

You could also implement it as a friend function that takes one parameter:

inline Fraction operator-( Fraction &one )

{

return Fraction( -one.numerator, one.denominator );

}

When you overload an operator using a friend function, you must make at least one of the function's parameters an object. That is, you cannot write a binary operator+ function that took two integers as parameters. This prevents you from redefining the meaning of operators on built-in types.

Notice that you have to define three separate functions to handle the addition of Fraction objects and long integers. If you overload other arithmetic operators, such as * or /, you must also provide three functions for each operator. A technique for avoiding multiple versions of each operator is described in the section “Class Conversions”.