Path: utzoo!utgpu!water!watmath!clyde!rutgers!sdcsvax!ucsdhub!hp-sdd!hplabs!well!mitsu From: mitsu@well.UUCP (Mitsuharu Hadeishi) Newsgroups: comp.lang.c++ Subject: Re: Operator overloading considered harmful Message-ID: <4971@well.UUCP> Date: 12 Jan 88 20:34:26 GMT References: <240@vsi1.UUCP> Reply-To: mitsu@well.UUCP (Mitsuharu Hadeishi) Organization: Whole Earth 'Lectronic Link, Sausalito, CA Lines: 68 Summary: The philosophy of C++ was similar to that of C: rather than trying to force programmers into good programming practice by limiting them to only "safe" procedures (forcing extensions to the language or creative practices such as those employed in the various dialects of Pascal), you give them the power to hang themselves; or save themselves a lot of hassle. It is possible to write structured, modular programs in C without too much difficulty; it is also possible to write unreadable and unstructured code. The facilities are there; you are free to use or abuse them as you wish. C++ has extended this philosophy even further. By providing all sorts of neat new features, one is now able to write code that approximates the object-oriented style. However, if not applied carefully, this can lead to disaster (such as the code fragment you mention.) However, operator overloading, if applied carefully, can give you tremendous leaps forward in both readability and stability of source code. For example, the type "varstr" which means "variable-length string" was defined here, and is used as follows: varstr a = "I am a"; varstr b = "I am b"; varstr c = a + b; varstr d = "I am d"; d += " " + a; cout << a << "\n" << b << "\n"; cout << c << "\n" << d << "\n"; This code is eminently readable, and what's more, we re-implemented varstr in two completely different ways, and yet the above code still worked. Why? Because the source code is at a higher level of abstraction than the implementation mechanism. I can change the implementation of operator+ from an inline to a function call, and this does not affect the source code. I can use reference count garbage collection to reduce unnecessary copying (thereby radically changing both the internal representation of varstr as well as changing the way one would use it inline) without modifying source. In C, such a change would be so radical one would have to completely rewrite any source code that manipulated such a beast (or resort to writing everything as function calls) and output and conversion between varstr and a normal C string would have to be changed (whereas before you might write varstr.str, afterward you might write varstr.p->str). In C++ you simply need to change the class declaration and modify a few inlines, and you need not change one line of source. Another great use of overloaded operators is the support of mathematical types. For example, in the early days of the Amiga the C compiler only supported a fairly cumbersome IEEE-standard floating point. There was, however, a built-in quick-but-inaccurate floating point that was useful for doing fast calculations. To get to it, though, you needed to do some horrible manipulations and calls to library functions; you couldn't just write a = b * c. With C++, however, one could easily create inline operators which did the conversion to the library function calls, obviating the need for a new compiler just to handle the different floating point calling conventions. And on an on. Of course, operator overloading can be misused much more easily than it can be used properly, but the same goes for the design of classes (it is easy to write a poorly designed class which works but ends up making code harder, not easier, to read.) C++ operator overloading is an indispensable and useful feature of the language, and like all powerful tools, not to be fooled with lightly. -Mitsu Hadeishi Electronic Arts