There are a lot of posts complaining about operator overloading.
I felt I had to clarify the "operator overloading" concepts, offering an alternative viewpoint on this concept.
Code obfuscating?
This argument is a fallacy.
It is as easy to obfuscate code in C or Java through functions/methods than it is in C++ through operator overloads:
// C++
T operator + (const T & a, const T & b) // add ?
{
T c ;
c.value = a.value - b.value ; // substract !!!
return c ;
}
// Java
static T add (T a, T b) // add ?
{
T c ;
c.value = a.value - b.value ; // substract !!!
return c ;
}
/* C */
T add (T a, T b) /* add ? */
{
T c ;
c.value = a.value - b.value ; /* substract !!! */
return c ;
}
For another example, let's see the Cloneable interface in Java: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Cloneable.html
You are supposed to clone the object implementing this interface. But you could lie. And create a different object. In fact, this interface is so weak you could return another type of object altogether, just for the fun of it:
class MySincereHandShake implements Cloneable
{
// etc.
public Object clone()
{
return new MyVengefulKickInYourHead() ;
}
}
Should the Cloneable interface be banned on the same grounds C++ operator overloading should be?
We could overload the toString method of a MyComplexNumber class to have it return the stringified hour of the day. Should the toString overloading be banned, too? We could sabotage MyCompletNumber.equals to have it return a random value...
In Java, as in C++, or whatever language, the programmer must respect a minimum of semantics when writing code. This means implementing a "add" function that adds, and Cloneable method that clones, and a ++ operator than increments.
What's obfuscating anyway?
Now that we know that code can be sabotaged even through the pristine Java methods, we can ask ourselves about the real use of operator overloading in C++?
It is used to add syntactic sugar:
Iterators:
// Java iterators
it.moveNext() ;
// C++ iterators ;
++it ;
--it ;
it += 5 ;
Comparisons:
// Java comparison
boolean isEqual = myString.equals(myOtherString) ;
// C++ comparison
bool isEqual = myGUID == myOtherGUID ;
bool isLesser = myGUID < myOtherGUID ;
bool isLesserOrEqual = myGUID <= myOtherGUID ;
Array accessors and subscripting:
// Java container accessors
myArray[25] ;
myVector.elementAt(25) ;
myMap.get("25") ;
my2DContainer.get(25, 42) ;
// C++ container accessors
myArray[25] ;
myVector[25] ;
myMap["25"] ;
my2DContainer(25, 42) ;
Advanced types:
// Java fictious advanced types
myMatrix = Matrix.multiply(myMatrixA, myMatrixB) ;
myMatrix = Matrix.multiply(Matrix.substract(myMatrixA, myMatrixB), Matrix.add(myMatrixC, myMatrixD)) ;
// C++ fictious advanced types
myMatrix = myMatrixA * myMatrixB ;
myMatrix = (myMatrixA - myMatrixB) * (myMatrixC + myMatrixD) ;
Functors:
// Java Functors ???
myFunctorObject.exec("Hello World", 42) ;
// C++ Functors
myFunctorObject("Hello World", 42) ;
String concatenation:
// Java concatenation
myStringBuffer.append("Hello ").append(25).append(" World") ;
// C++ stream handling
myStringStream << "Hello " << 25 << " World" ;
myFileStream << "Hello " << 25 << " World" ;
myOutputStream << "Hello " << 25 << " World" ;
myNetworkStream << "Hello " << 25 << " World" ;
myAnythingThatDerivesFromOStream << "Hello " << 25 << " World" ;
Ok, In Java you can use MyString = "Hello " + 25 + " World"... But, wait a second: This is operator overloading, isn't it? Isn't it cheating???
:-D
All in all, I wonder which language is really the less easy to read, when used by programmers (and not saboteurs, which seem to be quite numerous, according to the "operator overloading is evil" crowd).
The truth is that, like the toString(), clone(), equals() methods are for Java, C++ operator overloading is so much part of C++ that it becomes as natural as the original C operators, or the before mentioned Java methods.
In C, << and >> are used for bitwise operations. In C++, when used on streams, they are used to write or read. And in C++, you'll use more often the stream version than the bitwise version. The operator < and == is used implicitly by STL associative containers. supbscript [] is used on containers. function operator () is used for... functors. Etc. etc..
Combined with template programming, operator overloading becomes a well known design pattern. In fact, you cannot go very far in STL without using overloaded operators, and overloading operators for your own class.
Now, operator overloading should not be abused
Operator overloading should strive to respect the semantics of the operator. Do not substract in a + operator (as in "do not substract in a add function").
Cast overloadings are very dangerous because they can lead to ambiguities. So they should really be reserved for well defined cases. As for && and ||, do not ever overload them as the result will be surprising.
Why it is not possible in Java?
Because Java objects are used through references (i.e. nullable pointers without arithmetics). Thus, the operator = and == are already used to assign or compare references, not the values referenced.
Only concrete types would benefit from operator overloading, but Java's concrete types are primitives, and already have their operators assigned (like C++ operators for built-in types).
.
But they do it in C#!!!
Yeah...
This difference between Java and C# never fails to amuse me. Apparently, the C# folks, with their "every primitive is a struct, and a struct derives from Object", got it right at first try.