// File: ex6-5.cpp
#include <iostream>
#include <cassert>
using namespace std;
class Fraction
{
int numer, denom;
public:
Fraction(int = 0, int = 1);
void operator!() const; // print the Fraction
Fraction& operator~(); // reduce the Fraction
Fraction operator-() const; // negative of Fraction
Fraction operator*() const; // reciprocal of Fraction
Fraction& operator+=(const Fraction&);
Fraction& operator-=(const Fraction&);
Fraction& operator*=(const Fraction&);
Fraction& operator/=(const Fraction&);
Fraction operator+(int) const;
Fraction operator-(int) const;
Fraction operator*(int) const;
Fraction operator/(int) const;
bool operator>(const Fraction&) const;
bool operator<(const Fraction&) const;
bool operator>=(const Fraction&) const;
bool operator<=(const Fraction&) const;
bool operator==(const Fraction&) const;
bool operator!=(const Fraction&) const;
Fraction operator+(const Fraction&) const;
Fraction operator-(const Fraction&) const;
Fraction operator*(const Fraction&) const;
Fraction operator/(const Fraction&) const;
Fraction& operator++();
// prefix operator returns by reference
Fraction operator++(int); // postix operator returns by value
};
// member function definitions
Fraction::Fraction(int n, int d) : numer(n), denom(d)
{
assert(d != 0);
}
void Fraction::operator!() const {
cout << numer << '/' << denom << endl;
}
Fraction& Fraction::operator~() {
int min;
// find the minimum of the denom and numer
min = denom < numer ? denom : numer;
for (int i = 2; i <= min; i++)
{
while ((numer % i == 0) && (denom % i == 0))
{
numer /= i;
denom /= i;
}
}
return *this;
}
Fraction Fraction::operator-() const {
return Fraction(-numer,denom);
}
Fraction Fraction::operator*() const {
return Fraction(denom,numer);
}
Fraction& Fraction::operator+=(const Fraction& f) {
numer = numer*f.denom+denom*f.numer;
denom = denom*f.denom;
return *this;
}
Fraction& Fraction::operator-=(const Fraction& f) {
*this += (-f);
return *this;
}
Fraction& Fraction::operator*=(const Fraction& f) {
numer = numer*f.numer;
denom = denom*f.denom;
return *this;
}
Fraction& Fraction::operator/=(const Fraction& f) {
*this *= (*f);
return *this;
}
bool Fraction::operator>(const Fraction& f) const {
return (float) numer/denom > (float) f.numer/f.denom;
}
bool Fraction::operator<(const Fraction& f) const {
return f>*this;
}
bool Fraction::operator==(const Fraction& f) const {
return numer*f.denom == denom*f.numer;
}
bool Fraction::operator!=(const Fraction& f) const {
return !(*this == f);
}
bool Fraction::operator<=(const Fraction& f) const {
return !(*this > f);
}
bool Fraction::operator>=(const Fraction& f) const {
return !(*this<f);
}
Fraction Fraction::operator+(const Fraction& f) const {
return Fraction(numer*f.denom+denom*f.numer,denom*f.denom);
}
Fraction Fraction::operator-(const Fraction& f) const {
return Fraction(numer*f.denom-denom*f.numer,denom*f.denom);
}
Fraction Fraction::operator*(const Fraction& f) const {
return Fraction(numer*f.numer,denom*f.denom);
}
Fraction Fraction::operator/(const Fraction& f) const {
return (*this) * (*f);
}
Fraction Fraction::operator+(int i) const {
return Fraction(numer+i*denom,denom);
}
Fraction Fraction::operator-(int i) const {
return (*this) + -i;
}
Fraction Fraction::operator*(int i) const {
return Fraction(numer*i,denom);
}
Fraction Fraction::operator/(int i) const {
return Fraction(numer,i*denom);
}
// prefix increment operator
Fraction& Fraction::operator++() {
numer += denom;
return *this;
}
// postfix increment operator
Fraction Fraction::operator++(int) { // Note dummy int argument
Fraction temp(*this);
++*this;
// call the prefix operator
return temp;
}
int main()
{
Fraction f(3,4); // initialize Fraction f & g
Fraction g(1,2);
cout << "!f "; !f;
cout << "!g "; !g;
cout << endl;
cout << "-g "; !-g;
cout << "*g "; !*g;
Fraction h = g + f;
cout << endl;
cout << "h=g+f " << " !h "; !h;
cout << "!~h "; !~h;
cout << endl;
cout << "f+g "; ! (f + g);
cout << "f-g "; ! (f - g);
cout << "f*g "; ! (f * g);
cout << "f/g "; ! (f / g);
cout << endl;
cout << "f+=g "; !~(f+=g);
cout << "f-=g "; !~(f-=g);
cout << "f*=g "; !~(f*=g);
cout << "f/=g "; !~(f/=g);
cout << endl;
cout << "f<g " << (f<g) << endl;
cout << "f>g " << (f>g) << endl;
cout << "f==g " << (f==g) << endl;
cout << "f!=g " << (f!=g) << endl;
cout << "f<=g " << (f<=g) << endl;
cout << "f>=g " << (f>=g) << endl;
cout << endl;
cout << "f+5 "; !(f+5);
cout << "f-5 "; !(f-5);
cout << "f*5 "; !(f*5);
cout << "f/5 "; !(f/5);
cout << endl;
cout << "f+=5 "; f+=5; cout << "!~f "; !~f; // How does this work?
cout << "++f "; !++f; cout << "f="; !f;
cout << "f++ "; !f++; cout << "f="; !f;
}