Operator Overloading in C++: when to use it and why?
Tags: programming, computerscience
Published: 2021-04-14 02:50:24

For me, one of the best features of a language like C++ is their support of stylistic formatting: they give you the freedom to build a meta-language for your API in simplifying the user experience of people that would want to make transactions with your API -- they are more than just a syntax sugar you put on top, they let you convey meaning succinctly. In other languages like Java, where operator overloading is not supported, you would have to describe the name of the operator instead of their symbols. Consider this:

```Java
public class Main {
    public static void main(String [] args){
        Complex cmpx1 = new Complex(0,3);
        Complex cmpx2 = new Complex(1,3);
        
        cmpx1.add(cmpx2);
        cmpx1.print();
    }
}

class Complex{
    private int x;
    private int y;

    Complex(int x, int y){
        this.x = x;
        this.y = y;
    }

    Complex add(Complex obj){
        this.x += obj.x;
        this.y += obj.y;
        return obj;
    }

    public void print(){
        System.out.println(this.x+" + "+this.y + "i");
    }
}
```
Your only means to transact with a `Complex` object is to call their functions with the `dot` operator, i.e. `Complex.add(complexObj)`. Consider the same structure implemented in C++ with operator overloading:

```C++
#include <iostream>

class Complex{
private:
  int x, y;

public:
    Complex (const int &_x = 0, const int &_y = 0){
    x = _x;
    y = _y;
  }

  Complex operator+ (const Complex & obj){
    Complex result;
    result.x = x + obj.x;
    result.y = y + obj.y;
    return result;
  }
  
  friend std::ostream & operator<< (std::ostream & ss, const Complex & obj);
};

std::ostream & operator<< (std::ostream & stream, const Complex & obj){
  stream << obj.x << " + " << obj.y << "i";
  return stream;
}

int main (){
  Complex cmp1 (1, 3);
  Complex cmp2 (0, 3);

  std::cout << cmp1 + cmp2;
}
```

Notice that as we simplify the operations in `main`, we did a little more specifications within the class `Complex`. This is very common in designing software systems, and really shows the sophistication of a language like `C++` in this respect. Think of a layered expression in `Complex` structure, in Java it would have to look something like this `cmp1.add(cmp2.multiply(cmp3.subtract(cmp4)))` where in C++, it would be expressed as `cmp1 + cmp2*(cmp3 - cmp4)`. Keep in mind that the C++ [compiler imposes operator precedence](https://en.cppreference.com/w/cpp/language/operators) for evaluating your expressions. In other words, it is not possible to change the precedence, grouping, or number of operands of operators. 

Java remains consistent with their style, and they have good reasons for that: to prevent the abuse of notations and building a meta-language on top of their framework, in most cases, it can be problematic. But we can sort of agree that as long as we keep the semantic meaning of these operators for us, we are not breaking any rules and thereby remain consistent. A good sense to foresee when we are abusing the notation is if another developer would have to look at your implementation of the `+` or `-` operator, you are probably abusing your notations.  We want to make our class easy to use and hard to misuse.

---
## Technical documentation:
- cppeference.com (n.d.). Operator Overloading. https://en.cppreference.com/w/cpp/language/operators