#include <iostream>
#include <cassert>
using namespace std;

class Breuk {
public:
    Breuk();
    Breuk(int t);
    Breuk(int t, int n);
    int teller() const;
    int noemer() const;
    void plus(Breuk b);
    void abs();
private:
    int boven;
    int onder;
    void normaliseer();
};

int ggd(int n, int m) {
    if (n == 0) return m;
    if (m == 0) return n;
    if (n < 0) n = -n;
    if (m < 0) m = -m;
    while (m != n)
        if (n > m) n -= m;
        else m -= n;
    return n;
}

// Constructor roept andere constructor van dezelfde class aan.
// C++11
// Beschikbaar vanaf Visual Studio 2012 en GCC 4.7

Breuk::Breuk(): Breuk(0, 1) {
}

Breuk::Breuk(int t): Breuk(t, 1) {
}

Breuk::Breuk(int t, int n): boven(t), onder(n) {
    normaliseer();
}

int Breuk::teller() const {
    return boven;
}

int Breuk::noemer() const {
    return onder;
}

void Breuk::plus(Breuk b) {
    boven = boven * b.onder + onder * b.boven;
    onder *= b.onder;
    normaliseer();
}

void Breuk::abs() {
    if (boven < 0) boven = -boven;
}

void Breuk::normaliseer() {
    assert(onder != 0);
    if (onder < 0) {
        onder = -onder;
        boven = -boven;
    }
    int d(ggd(boven, onder));
    boven /= d;
    onder /= d;
}

int main() {
    Breuk b1(4);
    cout << "b1(4) = " << b1.teller() << '/' << b1.noemer() << endl;
    Breuk b2(23, -5);
    cout << "b2(23, -5) = " << b2.teller() << '/' << b2.noemer() << endl;
    Breuk b3(b2);
    cout << "b3(b2) = " << b3.teller() << '/' << b3.noemer() << endl;
    b3.abs();
    cout << "b3.abs() = " << b3.teller() << '/' << b3.noemer() << endl;
    b3 = b2;
    cout << "b3 = b2 = " << b3.teller() << '/' << b3.noemer() << endl;
    b3.plus(5);
    cout << "b3.plus(5) = " << b3.teller() << '/' << b3.noemer() << endl;

    const Breuk halve(1, 2);
    cout << "halve = " << halve.teller() << '/' << halve.noemer() << endl;

    b3 = halve;
    cout << "b3 = halve = " << b3.teller() << '/' << b3.noemer() << endl;

    cin.get();
    return 0;
}
