Member vs. Nonmember operator overloading
Consider the Rational class (header file)
  --   the whole thing:
rat2.h
In the Rational class, you saw operator overloading. For example,
consider the basic arithmetic operators:
Rational operator+(const Rational &) const;
Rational operator-(const Rational &) const;
Rational operator*(const Rational &) const;
Rational operator/(const Rational &) const;
In the
sample Rational main program
you saw that   5 + x didn't compile, giving an error
that no code was given to allow adding a Rational object
to an int.
An alternative way to overload these operators is to make
them global instead of member functions (similar to operator<<).
Typically you would include them in a similar manner to the
overloaded operator<< and operator>>. The .h file would include
the prototypes:
friend Rational operator+(const Rational &, const Rational &);
friend Rational operator-(const Rational &, const Rational &);
friend Rational operator*(const Rational &, const Rational &);
friend Rational operator/(const Rational &, const Rational &);
They now have two parameters since in a statement such as
  z = x + y;   both x and y are passed in. Notice that
there is no const at the end since they are not member functions.
The code for these routines is typically still found in the .cpp file
and is similar to the member function except you need to remember
to always qualify (put the object in front of the dot) all computations
involving members. For example, compare the member operator+
Rational Rational::operator+(const Rational& a) const {
Rational sum;
sum.numerator = a.numerator * denominator + a.denominator * numerator;
sum.denominator = a.denominator * denominator;
sum.reduce();
return sum;
}
with the nonmember operator+
Rational operator+(const Rational& leftop, const Rational& rightop) {
Rational sum;
sum.numerator = rightop.numerator * leftop.denominator
+ rightop.denominator * leftop.numerator;
sum.denominator = rightop.denominator * leftop.denominator;
sum.reduce();
return sum;
}