2

Which C++ operators can not be overloaded at all without friend function?

user366312
  • 16,949
  • 65
  • 235
  • 452

7 Answers7

4

You only need a friend declaration if:

  1. You define the operator as a standalone function outside the class, and
  2. The implementation needs to use private functions or variables.

Otherwise, you can implement any operator without a friend declaration. To make this a little bit more concrete... one can define various operators both inside and outside of a class*:

 // Implementing operator+ inside a class:
 class T {
   public:
    // ...
    T operator+(const T& other) const { return add(other); }
    // ...
 };

 // Implementing operator+ outside a class:
 class T {
   // ...
 };

 T operator+(const T& a, const T& b) { return a.add(b); }

If, in the example above, the "add" function were private, then there would need to be a friend declaration in the latter example in order for operator+ to use it. However, if "add" is public, then there is no need to use "friend" in that example. Friend is only used when granting access is needed.

*There are cases where an operator cannot be defined inside a class (e.g. if you don't have control over the code of that class, but would still like to provide a definition where that type is on the left-hand side, anyway). In those cases, the same statement regarding friend declarations still holds true: a friend declaration is only needed for access purposes. As long as the implementation of the operator function relies only on public functions and variables, a friend declaration is not needed.

Michael Aaron Safyan
  • 93,612
  • 16
  • 138
  • 200
  • Not true, there are also lhs operators. – Puppy Oct 24 '11 at 09:58
  • @DeadMG, nevermind. I believe your argument was with my wording over "one can define various operators both inside and outside of a class", not over the friend declaration? While it is still true, it is not always possible to modify the class, so I've clarified my wording. – Michael Aaron Safyan Oct 24 '11 at 10:10
  • You don't need a `friend` as long as the class exposes public interfaces to `get` and `set` the `private` or `prtotected` members. – Alok Save Oct 24 '11 at 10:10
2

The operators where the left-hand-side operand is not the class itself. For example cout << somtething can be achieved via defining a std::ostream& operator<<(std::ostream& lhs, Something const & rhs); function, and marking them as friend inside the class.

EDIT: Friending is not needed, ever. But it can make things simpler.

Notinlist
  • 16,144
  • 10
  • 57
  • 99
  • If the operator overloaded function needs to access only the public members of the class then it need not be `friend` to the class.Also,The overloaded operator could use `getter`, `setter` methods of class to access its members so it need not be necessarily a `friend`. – Alok Save Oct 24 '11 at 10:06
  • @BjörnPollex True. That is only a usual case. – Notinlist Oct 24 '11 at 13:58
  • 2
    @Als Setters? Why? About the getters: I think it is better to mark a function friend instead of writing boilerplate getter arsenal if it is not needed for other purposes. What is the point of OOP (esp. the concept of data hiding) if we define getters-setters for our every internal thing? Use struct instead when everything has getter-setter! – Notinlist Oct 24 '11 at 14:03
  • You misunderstand. If the getters and setters are already present then it makes no sense to have a friend, not the other way round. – Alok Save Oct 24 '11 at 14:57
  • @Als Yes, know I see. Sorry. :-) – Notinlist Oct 24 '11 at 15:25
1

The only reason to use friend function is to access the private(including protected) member variable and functions.

Simon Zhao
  • 56
  • 1
  • 4
1

You never need a friend function. If you don't want the operator to be a member (usually the case for binary operators which do not modify their operands), there's no requirement for it to be a friend. There are two reasons one might make it a friend, however:

  1. in order to access private data members, and
  2. in order to define it in the class body (even though it is not a member), so that ADL will find it

The second reason mainly applies to templates, but it's common to define operators like + and - in a template base class, in terms of += and -=, so this is the most common case.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
1

Operator overloading and friendship are orthogonal concepts. You need to declare a function (any function) friend whenever it needs access to a private member of the type, so if you overload an operator as a function that is not a member and that implementation needs access to the private members, then it should be friend.

Note that in general it is better not to declare friends, as that is the highest coupling relationship in the language, so whenever possible you should implement even free function overloads of operators in terms of the public interface of your type (allowing you to change the implementation of the type without having to rewrite the operators). In some cases the recommendation would be to implement operatorX as a free function in terms of operatorX= implemented as a public member function (more on operator overloading here)

There is an specific corner case, with class templates, where you might want to declare a free function operator as a friend of the template just to be able to define it inside the template class, even if it does not need access to private members:

template <typename T>
class X {
   int m_data;
public:
   int get_value() const { return m_data; }

   friend std::ostream& operator<<( std::ostream& o, X const & x ) {
      return o << x.get_value();
   }
};

This has the advantage that you define a single non-templated function as a friend in a simple straightforward way. To move the definition outside of the class template, you would have to make it a template and the syntax becomes more cumbersome.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
0

operators [] -> =

Must be a member functions.

Other binary operators acceptable for overloading can be write in function form or in memeber-function form. Operators acceptable for overloading is all unary and binary C++ operators except

: . :: sizeof typeid ?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Konstantin Burlachenko
  • 5,233
  • 2
  • 41
  • 40
0

You need to use a friend function when this is not the left-hand-side, or alternatively, where this needs to be implicitly converted.

Edit: And, of course, if you actually need the friend part as well as the free function part.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • 4
    You only need to use a friend in these cases if the operator cannot do it's work with access just to the public interface of the class, or am I missing something? – Björn Pollex Oct 24 '11 at 10:01