When you provide an operator overload for your type, what you are doing is providing a function to call when the operator appears in code. It does not make sense to provide two definitions when only one can be called and there is no way of selecting it.
That is, you should not have both a member function and a free function overload.
The next thing, which might actually be your confusion is what the meaning of friend
is. When you provide a friend declaration, you are declaring a free function and granting that function access to your private members. It is a free function, and as such there is no implicit this
argument, thus:
class X {
friend X operator+(X const &);
};
would declare an overload for operator+
that takes a single argument of type X const&
and returns an object of type X
. Incidentally, that is a valid operator, just not the one that you mean to overload (it is the unary operator+
, as in X x; +x;
). Going back to the previous paragraph, it declares a free function, not a member function, there is no implicit this
, just like if you had declared:
class X {};
X operator+(X const &);
And because there is no implicit this
, minutes
and hours
by themselves don't make sense inside that function and will fail to compile. (The friend
keyword in the definition is also wrong, friend
can never appear outside of a class definition).
There is some confusion as of whether friend
has any special meaning with respect to operators, it doesn't. It is just a keyword that affects access specifiers. If you can implement the operator in terms of the public interface of your type, it should not be friend
in the first place. So if for example you had accessors in Time
to obtain the hours and minutes, you could implement the operator as:
class Time { // ...
public:
Time(int hours, int minutes);
int hours() const;
int minutes() const;
};
Time operator+(Time const & lhs, Time const & rhs) {
return Time(lhs.hours()+rhs.hours(), lhs.minutes()+rhs.minutes());
}
With no friendship involved.