A simple Fraction class My code seems to work fine. However, I feel like it is a bit too long (fraction.cpp). I really want to create simple, readable, and efficient code.

Sample Run:


Here is the fraction.h file:

#ifndef FRACTION_H 
#define FRACTION_H
#include &lt;QString&gt;

class Fraction {

public:
     Fraction();
     Fraction(int numberator, int denominator);
     void set(int numberator, int denominator);
     QString toString() const;
     double toDouble() const;
     int findGCD(int a, int b);
     Fraction simplify();
     Fraction add(const Fraction&amp; other);
     Fraction substract(const Fraction&amp; other);
     Fraction multiphy(const Fraction&amp; other);
     Fraction divide(const Fraction&amp; other);

private:
     int m_Numerator;
     int m_Denominator;
};

#endif // FRACTION_H


Here is the fraction.cpp file:

#include "fraction.h"

// Constructors:
Fraction::Fraction()
    :m_Numerator(0), m_Denominator(0) {}

Fraction::Fraction(int numerator, int denominator)
    :m_Numerator(numerator), m_Denominator(denominator) {
}

// Setter method
void Fraction::set(int numberator, int denominator) {
    m_Numerator = numberator;
    m_Denominator = denominator;
}

// GCD
int Fraction::findGCD(int a, int b) {
    if (a == 0) 
        return b;
    return findGCD(b%a, a);
}

// Simplify
Fraction Fraction::simplify() {
    int gcd = findGCD(m_Numerator, m_Denominator);
    return Fraction::Fraction(m_Numerator / gcd, m_Denominator / gcd);
}

double Fraction::toDouble() const {
    return ((double) m_Numerator/m_Denominator);
}

QString Fraction::toString()const {
    return QString("%1 / %2 = %3")
        .arg(m_Numerator)
        .arg(m_Denominator)
        .arg(toDouble());
} 

Fraction Fraction::add(const Fraction &amp;other) {
    int numeratorTemp(m_Numerator);
    int denominatorTemp(m_Denominator);

    if (m_Denominator == other.m_Denominator) {
        numeratorTemp = m_Numerator + other.m_Numerator;
    } else {
        numeratorTemp = m_Numerator * other.m_Denominator + other.m_Numerator * m_Denominator;
        denominatorTemp = m_Denominator * other.m_Denominator;
    }
    return Fraction::Fraction(numeratorTemp, denominatorTemp);
}

Fraction Fraction::substract(const Fraction &amp;other) {
    int numeratorTemp(m_Numerator);
    int denominatorTemp(m_Denominator);

    if (m_Denominator == other.m_Denominator) {
        numeratorTemp = m_Numerator - other.m_Numerator;
    } else {
        numeratorTemp = m_Numerator * other.m_Denominator - other.m_Numerator * m_Denominator;
        denominatorTemp = m_Denominator * other.m_Denominator;
    }
    return Fraction::Fraction(numeratorTemp, denominatorTemp);
}

Fraction Fraction::divide(const Fraction &amp;other) {
    int numeratorTemp(m_Numerator);
    int denominatorTemp(m_Denominator);

    numeratorTemp = m_Numerator * other.m_Denominator;
    denominatorTemp = m_Denominator * other.m_Numerator;
    return Fraction::Fraction(numeratorTemp, denominatorTemp);
}

Fraction Fraction::multiphy(const Fraction &amp;other) {
    int numeratorTemp(m_Numerator);
    int denominatorTemp(m_Denominator);

    numeratorTemp  = m_Numerator * other.m_Numerator;
    denominatorTemp = m_Denominator * other.m_Denominator;
    return Fraction::Fraction(numeratorTemp, denominatorTemp);
}


Main.cpp:

#include &lt;QCoreApplication&gt;
#include &lt;iostream&gt;
#include "fraction.h"

int main() {
    using namespace std;

    Fraction frac1(1, 2);
    Fraction frac2(5, 2);

    cout &lt;&lt; "Addition: 1/2 + 5/2 = " &lt;&lt; frac1.add(frac2).simplify().toString().toUtf8().constData() &lt;&lt; "\n";
    cout &lt;&lt; "Substraction: 1/2 - 5/2 = " &lt;&lt; frac1.substract(frac2).simplify().toString().toUtf8().constData() &lt;&lt; "\n";
    cout &lt;&lt; "Divide: 1/2 : 5/2 = " &lt;&lt; frac1.divide(frac2).simplify().toString().toUtf8().constData() &lt;&lt; "\n";
    cout &lt;&lt; "Multiplication: 1/2 * 5/2 = " &lt;&lt; frac1.multiphy(frac2).simplify().toString().toUtf8().constData() &lt;&lt; "\n";
}


Output: https://i.stack.imgur.com/cnT9A.png
One thing that would help simplify your implementation is to fall back to already implemented code. For example, you could implement subtraction as addition using the negative of the second fraction. Likewise you could implement division as multiplication with the reciprocal of the second fraction.
Another point about readability: because you are implementing a mathematical notion which fits well with the standard arithmetic operations, consider adding +, *, etc as operators. As above, these operators could simply call the add, multiply, etc functions you already have. E.g. Fraction operator+(const Fraction&amp; other) {return add(other);}
Consider adding helper methods for negation and reciprocal. These could be private, and used only by the simplified subtract and divide as above, or they could be exposed as potentially useful to the class consumer.
Another simplification would be to avoid coding special cases when the general case works just as well. For example, when adding, you don't need to first check whether the denominators match.
To help avoid the numbers getting out of hand, you could call simplify as a matter of course when doing these operations.
Consider moving some of your functions into the private section of the class definition. Generally, things that are intended to be used by the class and are not intended to be used from outside should be private. findGCD looks like a good candidate for moving. (One advantage of doing this to readability is that someone who wants to use your class knows they're only meant to look at the public methods, so they don't get drowned in irrelevant options.)
Consider getting rid of the set function completely. According to everything else, Fraction objects are immutable and cannot be changed. Instead, each operation returns a new Fraction object. Having set breaks this convention, and actually isn't that helpful a feature.
Consider marking all your member functions const if they don't change the current Fraction object. For example, Fraction simplify() const;
Consider marking all your functions (and your constructors) constexpr if you are using c++14 or greater. This tells the compiler that it's allowed to do some calculations at compile time if it knows the inputs, saving you having to do them at runtime.
As a point of efficiency, int numeratorTemp(m_Numerator); is unnecessarily setting a variable that will then be immediately overwritten. Hopefully an optimising compiler would simply pretend that never happened, but you might as well jump straight to const int numeratorTemp = m_Numerator * other.m_Denominator; or as appropriate.
You could do with some checks against illegal numbers. In particular, any fraction with zero as a denominator including 0/0 as given in your default constructor is undefined, and you should probably throw an exception. (For the same reason, I'd make the default constructor return 0/1.)
Nitpicks.
Although you should make your classes fit with the convention of your broader codebase, all things being equal it's probably better to have toString in a generic class produce a standard string rather than a &lt;QString&gt;.
You have a typo in multiply as multiphy. You also want numerator instead of numberator and subtract instead of substract.
When calling a constructor, don't qualify it. E.g Fraction(n, d); rather than Fraction::Fraction(n, d);