Operators in C++ are things such as +, -, *, =. Now, if one has two variables of type int (which means they both represent integers), it's pretty clear how the "+" operator should work on them. It should add them, and return the result. Thus, the code fragment
     int foo, bar, baz;  //Declare integer variables "foo", "bar", and "baz"
     foo = 5;  //Set foo to 5
     bar =6;   //Set bar to 6
     baz = foo + bar;  
results in the variable baz having a value of 5+6, or 11.

But what if you want to add something other than one of the fundamental types. What if you have two objects of class Box? How do you add two boxes? It depends on the specific requirements of your program.

And, without operator overloading, one would have to declare, within the Box class a function such as this:

     Box Add(Box otherbox);
and use it like so
     box3 = box2.Add(box1);

Now, with operator overloading, we can merely declare a function called operator+ to overload the "+" operator. The declaration looks similar to the one above(and the code within the function would be identical):

     Box operator+(Box otherbox);
but now this is a valid statement
     box3 = box2 + box1;

The advantage to operator overloading is that it makes code much more readable. However, people who dislike it claim that it tends to make code more cryptic.

an example of operator overloading:

Say you want to add 2 complex numbers (in mathematics, a complex number is a number with 2 parts, a real and an imaginary, written like (1,2i) with the first number being the real number and the second being the imaginary.) Say you want to add 2 of these complex numbers (added as ((xr + yr), (xi + yi)i).) In C, you would probably devise a structure something like this to hold the data:

struct complex
{
double real;
double imag;
};

And you would add these two structs something like this, needing to devise a function that adds complex numbers and returns the sum:

added = addComplex(a, b);

But wouldn't it make more sense to be able to do it like this?

added = a + b;

Well, with operator overloading you can. Devise your class like this:

class complex
{
private:
double real;
double imag;
public:
complex();
~complex();
complex operator+(complex &);
};

You will, of course, need to define your class constructor (complex()) and your destructor (~complex()). Then, you tell the compiler how to overload the addition operator to add two of these classes together:

compex complex::operator+(comlex & cnum)
{
complex temp; // new temporary class

temp.real = real + cnum.real;
temp.imag = imag + cnum.imag;
return temp;
}

This enables the compiler to know how to add two of the same classes together. You can use any standard operator for C++ overloading.

Another cool feature of operator overloading is the ability to kind-of re-write the istream and ostream classes (those are the classes in C++ that deal with input/output, roughly equivalent to stdio.h in C) to be able to tell cout (basically printf()) to print the class merely by passing the class to the ostream.

I am not very good at explaining things, but I hope I have demonstrated to you the basics of C++ operator overloading.

One interesting part of operator overloading that has not been mentioned above is the ability to overload the "conversion operators". You can override the conversion operators to allow your user-defined types to be converted to either built-in types or other user-defined types.

A member function Class::operator X(), where X is a type name, defines behaviour for a conversion of Class to X. Note that lack of return value - the type is mentioned as part of the function name, and cannot be repeated as the return type. Leave the return type blank.

Consider a String class -

class String {
  private:
    char* data;
  public:
    operator char*();

    ...
};

String::operator char*() {
  return data;
}

int main() {
  String s = "foobar";
  char* c = s; // allows implicit conversion
}
Use this technique sparingly, ambiguities with user-defined and built-in operators are likely to be quite common.

You can overload these operators: (in C++):

, 	! 	!= 	% 	%= 	& 	& 	&& 	
&= ( ) * * *= + +
++ += – – –– –= –>
–>* / /= < << <<= <= =
== > >= >> >>= [ ] ^ ^=
| |= || ~ delete new

And you can't overload the following:

. 	.* 	:: 	?:	

You can't overload # and ##, either, but they're not really operators.

The following operators must be overloaded as a class member:

=	( )	[ ]	->

There are no operators which CAN'T be overloaded as a member, but if the left-hand operand isn't your class, it can't be a member. (The left-hand operand is the object on which the overloaded method is being called.) So like the stream insertion/extraction operators (<< and >>).

Operator overloading is a computer programming language construct found in object oriented languages such as C++ and C#. It is intended to make user-defined objects and methods be just as useful and convenient as the built-in ones.1

It is generally a bad idea.

All powerful programming language features are potentially dangerous in the wrong hands. Operator overloading, however, offers one of the most unfavourable power to danger ratios: not very powerful, and quite dangerous with it.

Operator overloading is a piece of syntactic sugar that allows you, given objects A, B and C, instead of writing A.Sum(B, C);, to code A = B + C;, just as if they were of built-in types, not user-defined object types. The compiler or runtime then searches for an appropriate operator overload in order to translate the latter into the former. Aside from mathematical operators, type casts can usually also be overridden, e.g. to automatically generate a string describing your object, or an integer value from it.

Since the languages that have operator overloading are generally strongly typed2, it does not actually allow you to write generic code that can also accept integers, unless the code is inside a template or the like.

Operator overloading offers the promise of convenience, but doesn't really add to the language. Anything that can be done with operator overloading can be done without it, in a more explicit format.

Though using operator overloads instead of method calls is aimed at increasing readability, they are easy to misread. Operator overloading introduces hidden code. Reading code such as A = B;, it's not obvious that an operator has been overridden somewhere else in the code to convert B's type to A's, and has been triggered by this line. You don't know if the person who coded this, for instance accounted for the possibility of B being null, or equal to A. You may get an error, and go looking for it, but the error is well hidden.

Overloading mathematical operators should be strongly avoided unless you happen to be coding a class that is a mathematical entity, which actually has mathematical operators defined on it, such as a class for a matrix, vector or complex number. This is not very common.


1) Thanks to jrn for pointing out the idea behind operator overloading.

2) The weakly typed Perl 6 being an exception. In perl 6, you can also create your own operators. This means that you don't have to re-use mathematical operators for obscure purposes. Oh no, your code can be rendered total opaque by assigning arbitrary meaning to random punctuation.

cjeris points out that in the LISP family of languages, particularly in CLOS, there is no need for operator overloading, as the language syntax makes it clear that the distinction between operator and method is an illusion. An addition operator would be used like (+ A B), and an addition method would be used like (+ A B).

An oft-overlooked feature of operator overloading in C++ is that certain operators often come in pairs. Take the classic example, the subscript operator:

// Of course, if this were real C++ we would
// most probably be using an STL container for this.
class IntList
{
public:
	const int& operator[](unsigned index) const;	// inspect only
	int& operator[](unsigned index);	// inspect or mutate
};

The two operators are nearly identical, with the only difference being the fact that one of them is a const method. In other words, we have performed const-overloading. Why do we do this?

Imagine that we have a constant object of type IntList. We can only call const methods on the object, as we are not allowed to modify a const object. Let's see how this helps the compiler help us:

const IntList list;

list[3] = 3;	// Error! The compiler automatically stops us from trying this.
		// As the const operator is used, we get an error from trying to
		// assign to a constant value.

int i = list[3];	// This is fine! Bear in mind that we couldn't even do this
			// without the const operator overload.
			

This works out great! The compiler will use the correct operator overload for const objects, and will prevent you from doing anything crazy. [] isn't the only operator that comes in pairs. You will most likely apply the same ideas to other operators that apply mutator/inspector semantics.

Log in or register to write something here or to contact authors.