Sunday, May 1, 2011

What's the best way to implement a operator overload?

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?

From stackoverflow
  • 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
    Robert Gould : many libraries also use operator() for function object processing
    anon : Indeed, and operator== is used by others, and... but I didn't want to overwhelm a beginner.
  • 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.

  • 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.

    Roger Pate : Don't return a const.
  • 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.

0 comments:

Post a Comment