8.5. Friend vs non-friend functions

Some operators must be implemented as member functions, operator=, operator[], and member access - both operator. and operator->>, because the language requires it. We have choices where we define the others.

Some are commonly implemented as non-member functions, because their left operand cannot be modified by you. The most prominent of these are the stream insertion and extraction operators. The left operands are stream classes from the standard library which you cannot change.

For operators where you have to choose to either implement them as a member function or a non-member function, use the following guidelines:

  1. If it is a unary operator, then implement it as a member function. For example, operator++.

  2. If a binary operator treats both operands equally then implement as a non-member function.

    Generally, neither operand is modified in this situation. The relational operators all fall into this category.

  3. If a binary operator does not treat both of its operands equally then consider making it a member function.

    If the left-hand side operator is modified in the operation, or the function returns the this pointer, then it should be a member function of the left hand operand type.

    Otherwise, it can be implemented as a non-member function.

In the previous section, the relational operators were all declared as non-friend non-member functions. This is considered best practice by many programmers.

Prefer writing non-friend non-member functions

—Item 44 of C++ Coding Standards, by Herb Sutter and Andrei Alexandrescu

Compare to the functionally similar friend, member overload for operator==:

friend bool operator==(const item& x, const item& y) {
  return x.value == y.value;
}

You have attempted of activities on this page