# Operator Overloading in C++

My thoughts on Operator Overloading are hardly a secret. Some languages, such as Haskell, support it in a sane manner. Some languages, such as C++ don’t. Either way though, I’m not a fan.

That said, there is one case where I support it; when what you are trying to overload an operator to do makes sense for your type. In other words, if it makes sense to multiply an Employee object, feel free to overload the multiplication operator. Since we don’t usually model mating when we implement an employee object, I don’t usually approve.

## Multiplying a Fraction

However, if we have a fraction class, that has a numerator and denominator component, overloading the multiplication operator suddenly becomes reasonable:

```
frac<T> operator *(const frac<T> & rhs) const
{
return frac<T>(numer * rhs.numer, denom * rhs.denom);
};
```

In C++, many of the built in operators are available to be overloaded. You can do basically anything in an operator overload, but if you do, that makes you a bad person. Here we have a straightforward implementation, that I’m going to assume you don’t need to have explained to you. But let’s talk `const`

correctness.

In this signature, the `const`

appears twice. The right hand side argument is a `const`

reference. Since this is a reference, no copy occurs, but with references can come mutability. The `const`

here prevents any mutation from occurring. There is also a `const`

at the end of the signature. That means that this function cannot modify the `this`

pointer.

This function returns a new `frac<t>`

, so no need for `const`

there.

## Convert a Fraction to a Double

Next, you can overload the casting operator, and if you are a good person you’ll use this for type conversions. Let’s implement `(double)`

for our fraction:

```
operator double() const
{
return (double) numer / denom;
}
```

This code is pretty straight forward. We divide the numerator by the denominator, and cast it to double in case integer division occurs. Cast operator overloads don’t have a return type, which is a bit strange but something we can work with.

## Streaming operators

Finally, I’d like to talk about streaming operator overloads. For any overloaded operator, there are two forms: member and non-member. Member overloads take `n - 1`

arguments, where the minus 1 is the current object (and the left hand side). Non member overloads can’t access the this pointer, so they need to take the left hand side as a parameter.

Member overloads obviously have access to private class members, which makes them more powerful than non-member. Which leads us to the streaming operators. Streaming operators need to return `std::ostream &`

, so they *must* be non-member. The problem is that we want to print the private numerator and denominator fields. The solution? make it a friend:

```
friend std::ostream & operator <<(std::ostream & lhs,
const frac<T> & rhs)
{
lhs << rhs.numer << '/' << rhs.denom;
return lhs;
};
```

With that problem solved, this function becomes pretty straight forward. We stream the fields, formatted correctly, into the left hand side `std::ostream &`

, then we return the left hand side argument for further use by the next part of the streaming chain.