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?
-
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 processinganon : 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,
friendis 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
MatrixorPolynomialmultiplication as the*=(T const&)operator is not that trivial. In that case, we would defineoperator*=(T const&)on top ofoperator*(T const&, T const&), and the binaryoperator*()could be madefriendif there is no accessor to the internal data -- this use offriendis 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