Overloading Operators


Definition [1]


This can be a weird subject for some, especially those with a strong Java background, or another language that doesn't support this feature. It can be confusing even for excellent programmers But it is a strong feature of C++ that, if mastered, can yield some increased productivity in programming.

We all know that an operator can be used in mathematical expressions:

int z=x+y;
float g=3.14*g;

Now wouldn't it be nice to use operators on our own objects to do what we want? For example, a string class could use + to concatenate, or a Throttle class could use the ++ and -- operators to increase or decrease throttle position. The operators can be programmed to do whatever we want them to.

However, some words of caution. Operator overloading provides NO additional functionality to your code. It just compiles to normal function calls. It's even written out like normal function calls. It is mainly for aesthetics. There is, however, one extremely useful set of operators to overload that makes life much easier: the streaming operators.

Second, you should NOT use operator overloading for unobvious relationships. Using + to concatenate two strings intuitively makes sense to most programmers, so it's easy to use it like that. But how would you define string1*string2? or string1^string2? It isn't very clear what that means. So use caution when considering adding operators to your objects.

The following operators can be overloaded:
+    -    *    /    =    <    >    +=   -=   *=   /=   <<   >>
<<= >>= == != <= >= ++ -- % & ^ ! |
~ &= ^= |= && || %= [] () , ->* -> new
delete new[] delete[]

Example [2]


Here you have an example that overloads the addition operator (+). We are going to create a class to store bidimensional vectors and then we are going to add two of them: a(3,1) and b(1,2). The addition of two bidimensional vectors is an operation as simple as adding the two x coordinates to obtain the resulting x coordinate and adding the y coordinates to obtain the resulting y coordinate . In this case the result will be (3+1,1+2) = (4,3). coordinates to obtain the resulting
// vectors: overloading operators example
#include <iostream>
using namespace std;

class CVector {
public:
int x,y;
CVector () {};
CVector (int,int);
CVector operator + (CVector);
};

CVector::CVector (int a, int b) {
x = a;
y = b;
}

CVector CVector::operator+ (CVector param) {
CVector temp;
temp.x = x + param.x;
temp.y = y + param.y;
return (temp);
}

int main () {
CVector a (3,1);
CVector b (1,2);
CVector c;
c = a + b;
cout << c.x << "," << c.y;
return 0;
}

Although the prototype of a function operator+ can seem obvious since it takes what is at the right side of the operator as the parameter for the operator member function of the object at its left side, other operators may not be so obvious. Here you have a table with a summary on how the different operator functions have to be declared (replace @ by the operator in each case):

Expression Operator Member function Global function
@a + - * & ! ~ ++ -- A::operator@() operator@(A)
a@ ++ -- A::operator@(int) operator@(A,int)
a@b + - * / % ^ & | < > == != <= >= << >> && || , A::operator@ (B) operator@(A,B)
a@b = += -= *= /= %= ^= &= |= <<= >>= [] A::operator@ (B) -
a(b, c...) () A::operator() (B, C...) -
a->x -> A::operator->() -


Q1: For the above example, implement the following operators:
- CVector operator - (CVector);
- CVector operator >> (CVector);
-
bool operator==(const CVector &L) const;

General Rules [3]


  1. You cannot define new operators, such as **.
  2. You cannot redefine the meaning of operators when applied to built-in data types.
  3. Overloaded operators must either be a nonstatic class member function or a global function. A global function that needs access to private or protected class members must be declared as a friend of that class. A global function must take at least one argument that is of class or enumerated type or that is a reference to a class or enumerated type.
  4. Operators obey the precedence, grouping, and number of operands dictated by their typical use with built-in types. Therefore, there is no way to express the concept add 2 and 3 to an object of type Point, expecting 2 to be added to the x coordinate and 3 to be added to the y coordinate.
  5. Unary operators declared as member functions take no arguments; if declared as global functions, they take one argument.
  6. Binary operators declared as member functions take one argument; if declared as global functions, they take two arguments.
  7. If an operator can be used as either a unary or a binary operator (&, *, +, and -), you can overload each use separately.
  8. Overloaded operators cannot have default arguments.
  9. All overloaded operators except assignment (operator=) are inherited by derived classes.
  10. The first argument for member-function overloaded operators is always of the class type of the object for which the operator is invoked (the class in which the operator is declared, or a class derived from that class). No conversions are supplied for the first argument.


References:
[1]- http://www.devarticles.com/c/a/Cplusplus/Operator-Overloading-in-C-plus/1/
[2]- http://www.cplusplus.com/doc/tutorial/classes2.html
[3]- http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/overl_10.asp