# Example of overriding operators in C++ using a class that deals with fractions

C++ allows for the ability to overwrite operators. This program shows an example using various operators in a class that deals with fractions. It also throws a runtime exception if a divide by zero is attempted.

## Source Code

### main.cpp

``````#include "fraction.h"

int main()
{

Fraction a; // Value is 0/1
Fraction b(4); // Value is 4/1
Fraction c(6, 8); // Value is 6/8, which is converted to 3/4
cout << "Constructed values " << a << " " << b << " " << c << "\n";
cout << "Value of c is " << c.numerator() << "/" << c.denominator() << "\n";
// Test arithmetic instructions
Fraction d = b + c;
cout << "4 + 3/4 is " << d << "\n";
d = b - c;
cout << "4 - 3/4 is " << d << "\n";
Fraction e = (b + (-c));
cout << e << " done with negation\n";
if (d == e) cout << "Subtraction test successful\n";
a = Fraction(6, 8);
b = Fraction(7, 8);
if (a < b) cout << "Compare successful\n";

Fraction f(3, 0);

return 0;
}
``````

### fraction.h

``````#ifndef FRACTION_H
#define FRACTION_H
#include <iostream>

using namespace std;

class Fraction
{
public:
Fraction();
Fraction(int t);
Fraction(int t, int b);
int numerator() const;
int denominator() const;
Fraction& operator+=(const Fraction& right);
Fraction& operator++();
Fraction operator++(int unused);
int compare(const Fraction& right) const;
private:
void normalize();
int gcd(int n, int m);
int top;
int bottom;
};

Fraction operator+(const Fraction& left, const Fraction& right);
Fraction operator-(const Fraction& left, const Fraction& right);
Fraction operator*(const Fraction& left, const Fraction& right);
Fraction operator/(const Fraction& left, const Fraction& right);
Fraction operator-(const Fraction& value);
bool operator<(const Fraction& left, const Fraction& right);
bool operator<=(const Fraction& left, const Fraction& right);
bool operator==(const Fraction& left, const Fraction& right);
bool operator!=(const Fraction& left, const Fraction& right);
bool operator>=(const Fraction& left, const Fraction& right);
bool operator>(const Fraction& left, const Fraction& right);
ostream& operator<<(ostream& out, const Fraction& value);
istream& operator>>(istream& in, Fraction& r);

#endif
``````

### fraction.cpp

``````#include "fraction.h"
#include <cassert>
#include <stdexcept>

int Fraction::gcd(int n, int m)
{
assert((n > 0) && (m > 0));
while (n != m)
{
if (n < m)
m = m - n;
else
n = n - m;
}
return n;
}

Fraction::Fraction(int t, int b) : top(t), bottom(b)
{
if (b == 0) throw runtime_error("divide by zero exception thrown");
normalize();
}

Fraction::Fraction() : top(0), bottom(1) {}

Fraction::Fraction(int t) : top(t), bottom(1) {}

int Fraction::numerator() const
{
}

int Fraction::denominator() const
{
return bottom;
}

void Fraction::normalize()
{
int sign = 1;
if (top < 0)
{
sign = -1;
top = -top;
}
if (bottom < 0)
{
sign = -sign;
bottom = -bottom;
}
assert(bottom != 0);
int d = 1;
if (top > 0) d = gcd(top, bottom);
top = sign * (top / d);
bottom = bottom / d;
}

Fraction operator+(const Fraction& left, const Fraction& right)
{
Fraction result(left.numerator() * right.denominator()
+ right.numerator() * left.denominator(),
left.denominator() * right.denominator());
return result;
}

Fraction operator-(const Fraction& left, const Fraction& right)
{
Fraction result(left.numerator() * right.denominator()
- right.numerator() * left.denominator(),
left.denominator() * right.denominator());
return result;
}

Fraction operator*(const Fraction& left, const Fraction& right)
{
Fraction result(left.numerator() * right.numerator(),
left.denominator() * right.denominator());
return result;
}

Fraction operator/(const Fraction& left, const Fraction& right)
{
Fraction result(left.numerator() * right.denominator(),
left.denominator() * right.numerator());
return result;
}

Fraction operator-(const Fraction& value)
{
Fraction result(-value.numerator(), value.denominator());
return result;
}

int Fraction::compare(const Fraction& right) const
{
return numerator() * right.denominator()
- denominator() * right.numerator();
}

bool operator<(const Fraction& left, const Fraction& right)
{
return left.compare(right) < 0;
}

bool operator<=(const Fraction& left, const Fraction& right)
{
return left.compare(right) <= 0;
}

bool operator==(const Fraction& left, const Fraction& right)
{
return left.compare(right) == 0;
}

bool operator!=(const Fraction& left, const Fraction& right)
{
return left.compare(right) != 0;
}

bool operator>=(const Fraction& left, const Fraction& right)
{
return left.compare(right) >= 0;
}

bool operator>(const Fraction& left, const Fraction& right)
{
return left.compare(right) > 0;
}

ostream& operator<<(ostream& out, const Fraction& value)
{
out << value.numerator() << "/" << value.denominator();
return out;
}

istream& operator>>(istream& in, Fraction& r)
{
int t, b;
in >> t;
char c;
in >> c;
if (c == '/')
in >> b;
else
{
in.unget();
b = 1;
}
r = Fraction(t, b);
return in;
}

Fraction& Fraction::operator++()
{
top += bottom;
return *this;
}

Fraction Fraction::operator++(int unused)
{
Fraction clone(top, bottom);
top += bottom;
return clone;
}

Fraction& Fraction::operator+=(const Fraction& right)
{
top = top * right.denominator() + bottom * right.numerator();
bottom *= right.denominator();
normalize();
return *this;
}``````