// Werken met breuken in C++ ... een eerste stap naar een ADT

#include <iostream>
#include <cassert>
using namespace std;

class Breuk {                 // Op een object van de class Breuk
public:                       // kun je de volgende bewerkingen uitvoeren:
	void leesin();              //    inlezen vanuit het toetsenbord.
	void drukaf() const;       //    afdrukken op het scherm.
	void plus(const Breuk& b); //    een Breuk erbij optellen.
private:                      // Een object van de class Breuk heeft privé:
	int boven;                  //    een teller,
	int onder;                  //    een noemer en
	void normaliseer();        //    een functie normaliseer.
};

void Breuk::leesin() {
	cout<<"Type een breuk (2 getallen gescheiden door een spatie): ";
	cin>>boven>>onder;
	assert(onder!=0);
	normaliseer();
}

void Breuk::drukaf() const {
	cout<<boven<<"/"<<onder<<endl;
}

void Breuk::plus(const Breuk& b) {
	boven=boven*b.onder + onder*b.boven;
	onder*=b.onder;
	normaliseer();
}

unsigned int ggd(unsigned int n, unsigned int m) {
	if (n==0) return m;
	if (m==0) return n;
	while (m!=n)
		if (n>m) n-=m;
		else m-=n;
	return n;
}

void Breuk::normaliseer() {
	if (onder<0) {
		onder=-onder;
		boven=-boven;
	}
	int d(ggd(boven<0?-boven:boven,onder));
	boven/=d;
	onder/=d;
}

int main() {
	Breuk a, b;	// definieer de objecten a en b van de class Breuk
	a.leesin();	// lees a in
	b.leesin();	// lees b in
	a.plus(b);	// tel b bij a op
	a.drukaf();	// druk a af

	cin.get();
	cin.get();
	return 0;
}