views:

228

answers:

4

Among all things I've learned in C++ (which isn't so much), operator overloading seems the most difficult. In general terms, when is it best to write an operator overload as a friend function? When do I have to explicilty use *this? Is always bad to use a temporary object?

+4  A: 

There is nothing magical abourt operator overloading - such overloads are simply functions with strange-looking names. So you write operator overloads in the same way you would write a named function. In fact, it's often a good idea to write a named function first - you can always change it to an operator later.

The only thing that you do have to be aware of is that the compiler makes use of a couple of your operators:

  • operator=() when storing things in collections
  • operator<() when sorting/searching things
anon
many libraries also use operator() for function object processing
Robert Gould
Indeed, and operator== is used by others, and... but I didn't want to overwhelm a beginner.
anon
+2  A: 

Neil's answer is correct. In addition, this link provides a lot of good information about when, where, why, and how to use the various types of operator overloading in C++.

In general, I'd try to stick with overloads that are intuitive -- use of the '+' operator should reflect something analogous to addition, etc. If you find yourself doing string comparisons with the '+' operator or something like that, you should probably be using standard functions instead.

mwigdahl
+1  A: 

The first rule of operators overloading: do not overload operators that make no sense. For instance, the + operator may look like a good choice to append elements to lists, but it is not: not everybody would find this use logical.

Regarding the mathematical operators, friend is unneeded.

The typical way to define them (that respects symmetries and implicit conversions) is the following one:

struct T {
    T& operator+=(T const& rhs) {
        // the actual addition code
        return *this;
    }
};
T const operator+(T const& lhs, T const& rhs) {
     return T(lhs) += rhs;
};

However, this organization is not adapted to operators like Matrix or Polynomial multiplication as the *=(T const&) operator is not that trivial. In that case, we would define operator*=(T const&) on top of operator*(T const&, T const&), and the binary operator*() could be made friend if there is no accessor to the internal data -- this use of friend is not an encapsulation violation, but an encapsulation enforcement --, or for optimization purposes.

If you really want to eliminate most temporaries, have a look at expression templates (see Blitz++, boost.ublas, newmat, ...), or wait for C++0x rvalue references.

Luc Hermitte
Don't return a const.
Roger Pate
A: 

All operators overloads as member-function take *this as lvalue,so you need friend in cases you don't want it such overload stream operators as << and >>.In most others cases the use of friends is to break the principle of least privilege. Other way to overload an operator ,which wasn't said, is to use a global function.

Hai