4

From language design point of view , What type of practice is supporting operator overloading?

What are the pros & cons (if any) ?

BobbyShaftoe
  • 28,337
  • 7
  • 52
  • 74
Nikhil Garg
  • 3,944
  • 9
  • 30
  • 37

5 Answers5

16

EDIT: it has been mentioned that std::complex is a much better example than std::string for "good use" of operator overloading, so I am including an example of that as well:

std::complex<double> c;
c = 10.0;
c += 2.0;
c = std::complex<double>(10.0, 1.0);
c = c + 10.0;

Aside from the constructor syntax, it looks and acts just like any other built in type.


The primary pro is that you can create new types which act like the built in types. A good example of this is std::string (see above for a better example) in c++. Which is implemented in the library and is not a basic type. Yet you can write things like:

std::string s = "hello"
s += " world";
if(s == "hello world") {
    //....
}

The downside is that it is easy to abuse. Poor choices in operator overloading can lead to accidentally inefficient or unclear code. Imagine if std::list had an operator[]. You may be tempted to write:

for(int i = 0; i < l.size(); ++i) {
    l[i] += 10;
}

that's an O(n^2) algorithm! Ouch. Fortunately, std::list does not have operator[] since it is assumed to be an efficient operation.

Evan Teran
  • 87,561
  • 32
  • 179
  • 238
  • 1
    "A good example" with the obvious caveat that defining operator+ for strings is a little bit icky... ,9 – jalf Jul 06 '10 at 08:47
  • 2
    Why is this a good example? `operator+` is commutative for all built-in types, but not for `std::basic_string`, so one could even say this is an abuse of operator overloading. `std::complex` might serve as a better example. – Philipp Jul 06 '10 at 09:22
  • Fair enough, `operator+` is unfortunately common enough to mean "append" in languages that it's convenience sometimes is viewed as more important than its consistency. I've added a `std::complex` example. – Evan Teran Jul 06 '10 at 14:44
13

The initial driver is usually maths. Programmers want to add vectors and quaternions by writing a + b and multiply matrices by vectors with M * v.

It has much broader scope than that. For instance, smart pointers look syntactically like normal pointers, streams can look a bit like Unix pipes and various custom data structures can be used as if they were arrays (with strings as indexes, even!).

The general principle behind overloading is to allow library implementors to enhance the language in a seamless way. This is both a strength and a curse. It provides a very powerful way to make the language seem richer than it is out of the box, but it is also highly vulnerable to abuse (more so than many other C++ features).

Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
  • I agree when you say it is both a strength and a curse, but every strength in programming is also a curse, isnt' it? Anything can be misused. Operator overloading allows programmers to make even worse interfaces, allowing one to set variables (imperative programming) lets programmers create bad variable names, reflection allows programmers to mess up their objectcontext, debuggers make programmers less careful, and IDEs make programmers lazy. I would consider all of those things have a positive affect on programming, but they all have the possibility they're misused. – B T Mar 15 '11 at 23:56
  • @B T: These are all motherhood statements. If absolutely anything can be characterised as both a strength and a curse, then the phrase becomes meaningless. Clearly, my intent was to convey the notion that operator overloading is especially prone to abuse, to a degree that the ability to set variables or create arrays, or iterate in a loop, or call functions aren't. – Marcelo Cantos Mar 16 '11 at 00:16
6

Pros: you can end up with code which is simpler to read. Few people would argue that:

BigDecimal a = x.add(y).divide(z).plus(m.times(n));

is as easy to read as

BigDecimal a = ((x + y) / z) + (m * n); // Brackets added for clarity

Cons: it's harder to tell what's being called. I seem to remember that in C++, a statement of the form

a = b[i];

can end up performing 7 custom operations, although I can't remember what they all are. I may be slightly "off" on the example, but the principle is right - operator overloading and custom conversions can "hide" code.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Just one, as far as I can tell. It should invoke the assignment operator. Of course, that might invoke as many other operations as it likes. (`A a = b` on the other hand, would've called the copy constructor ;)) – jalf Jul 06 '10 at 08:49
  • It can also apply a conversion. – visitor Jul 06 '10 at 09:07
1

You can do some interesting tricks with syntax (i.e. streams in C++) and you can make some code very concise. However, you can have the effect of making code very difficult to debug and understand. You sort of have to constantly be on your guard about the effects of various operators of different kinds of objects.

BobbyShaftoe
  • 28,337
  • 7
  • 52
  • 74
  • 1
    The C++ `<<` and `>>` operators are the canonical *bad* example of operator overloading. Their use for streams has nothing to do with their original meaning. – dan04 Jul 06 '10 at 05:39
  • @dan04: On the other hand, `<<` and `>>` are pretty pathetic built in operators on their own. They have no meaning to people unfamiliar with C and its ilk, they are only defined for a subset of the built in types, and even for types they do work on the results are not always well defined. They may illustrate bad overloading, but they also illustrate why guidelines can sometimes be bent to good use. – Dennis Zickefoose Jul 06 '10 at 15:30
0

You might deem operator overloading as a kind of method/function overloading. It is part of polymorphism in object oriented language.

With overloading, each class of objects work like primitive types, which make classes more natural to use, just as easy as 1 + 2.

Say a complex number class, Complex. Complex(1,2i) + Complex(2,3i) yields Complex(3,5i). 5 + Complex(3, 2i) yields Complex(8, 2i). Complex(2, 4i) + -1.8 yields Complex(0.2, 4i).

It is much easier to use class this way. If there is no operator overloading, you have to use a bunch of class methods to denote 'add' and make the notation clumsy.

The operator overloading ought to be defined carefully; otherwise, comes confusion. For example, '+' operator is natural to adding numbers, time, date, or concatenation of array or text. Adding '+' operator to a class of Mouse or Car might not make any sense. Sometimes some overloading might not be seem natural to some people. For example, Array(1,2,3) + Array(3,4,5). Some might expect Array(4,6,8) but some expect Array(1,2,3,3,4,5).

OmniBus
  • 854
  • 1
  • 6
  • 25