[comp.lang.c++] Operator overloading: good style?

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.