myers@over.cs.caltech.edu (Bob Myers) (02/19/90)
I'd like to hear opinions on operator overloading from a stylistic viewpoint.
When is it a good idea?
There are some cases that seem very clear to me, but others I have used
seem a little questionable to me now.
Example:
I had a vector3d class I implemented when I first learned C++ about 3 years
ago:
----------
class vector3d {
double x, y, z;
public:
vector3d() { x=0; y=0; z=0; }
vector3d(double x0, double y0, double z0) { x=x0; y=y0; z=z0; }
vector3d operator-(); // Vector negation
vector3d operator+(const vector3d&); // Vector addition
vector3d operator-(const vector3d&); // Vector subtraction
vector3d operator*(double); // Scalar multiplication
friend vector3d operator*(double, const vector3d&); // Scalar multiplication
vector3d operator/(double); // Scalar division
vector3d operator%(const vector3d&); // Cross product
vector3d operator^(double); // x-axis rotation
vector3d operator&(double); // y-axis rotation
vector3d operator|(double); // z-axis rotation
// ... etc ...
}
----------
You get the idea. Anyway, some of this stuff seemed like obvious
candidates for overloading: + - * / for example. However, the
overloaded % ^ & | are not at all related to the "standard" C
operators. They seemed to be useful operators at the time, however,
most particularly the % for cross product.
But what about the rotation operators? I found them useful, but will
anyone be able to read my code later? It is, I'll admit, difficult to
remember which operator rotates the vector about which axis. Is this
sort of thing a bad candidate for overloading? What do you think?
---------------------------------------------------------------------------
Bob Myers myers@through.cs.caltech.edu
jimad@microsoft.UUCP (Jim ADCOCK) (02/28/90)
In article <MYERS.90Feb18231352@over.cs.caltech.edu> myers@over.cs.caltech.edu (Bob Myers) writes: > >I'd like to hear opinions on operator overloading from a stylistic viewpoint. >When is it a good idea? When you really are working with mathematical types -- complex numbers, vectors, ratios, matrices, overloading standard operators to mean standard things is a godsend to users -- to have to learn a.add(b) instead of a + b -- and what [no] rules of precedence -- is to throw away decades of math experience for the average user. Look at Smalltalk manual, where math uses postfix keywords without mathematical precedence to see what the wrong way to do things is. But, where more than one operator in your math class can be mapped to a given operator, or if there is no *exactly* matching operator in C++, you'll cause a lot less confusion by creating an appropriate friend function or member function. I haven't decided whether friend or member is better in the following scenerio: complex c(123.0, 456.0); double d = imag(c) //or double d = c.imag(); I fudge and do both. I claim that if you're going to do overloaded math classes you have to really get them right, and make them so complete that people don't have to keep referring to your code or documentation to see how to use them. The idea is to have your class *exactly* match mathematical experience. Likewise, you need to seriously consider how you're going to handle math exceptions. The goal is to make your math class look as if it part of the CPU's hardware. IE built-in. Further, I claim overloading op= is a good thing to do in general, for almost all classes. A fuzzier area in my mind is classes representing obscure math, or classes where programmers have become mentally ingrained in thinking of those classes *not* in mathematical terms. Examples being sets or associative arrays. Are these better off given math notation or descriptive names? I don't know. Right now I fudge and say if they are the kind of things that the customers of your class are going to be working with on a day to day basis, maybe use operators. Otherwise function names will be more mnemonic, and will help remind people what it is they wrote. Fundamentally, do whatever is better for the people who are going to have to *read* the code written using these classes.