Ziel dieses Übungsbeispiels ist es, Operator-Overloading und Exception-Handling in einem kurzen Programm zu implementieren.
Ziel dieses Übungsbeispiels ist es, Operator-Overloading und Exception-Handling in einem kurzen Programm zu implementieren.
### Aber um was geht es denn?
### Aber worum geht es denn?
Es soll eine Klasse `Fraction`, die einen Bruch - also eine rationale Zahl - darstellt, erstellt werden. Nach fertiger Implementierung soll mit dieser Klasse wie mit gewöhnlichen `int` oder `double` mit den Operatoren `+`, `*`, `==` ... gerechnet werden können.
Es soll eine Klasse `Fraction`, die einen Bruch - also eine rationale Zahl - darstellt, erstellt werden. Nach fertiger Implementierung soll mit dieser Klasse wie mit gewöhnlichen `int` oder `double` mit den Operatoren `+`, `*`, `==` ... gerechnet werden können.
Beim Rechnen mit Brüchen ist außerdem zu beachten, dass der Nenner nie `0` werden darf. Insbesondere beim Erstellen eines neues Bruchs, aber auch beispielsweise beim Dividieren könnte es hier zu einem Problem kommen. Dafür soll eine eigene Exception `NullDivisionException` implementiert werden.
Beim Rechnen mit Brüchen ist außerdem zu beachten, dass der Nenner nie `0` werden darf. Insbesondere beim Erstellen eines neuen Bruchs, aber auch beispielsweise beim Dividieren könnte es hier zu einem Problem kommen. Dafür soll eine eigene Exception `NullDivisionException` implementiert werden.
## Klasse Fraction
## Klasse Fraction
Die Klasse `Fraction` soll genau einen Bruch darstellen. Dafür werden zwei Attribute benötigt, nämlich ein Zähler (`nominator_`) und ein Nenner (`denominator_`).
Die Klasse `Fraction` soll genau einen Bruch darstellen. Dafür werden zwei Attribute benötigt, nämlich ein Zähler (`nominator_`) und ein Nenner (`denominator_`).
Ein Bruch soll intern nach jeder Operation immer in gekürzter Form gespeichert sein und der Nenner soll immer positiv sein. Beispielsweise `5/-15` soll als `-1/3` gespeichert werden.
Ein Bruch soll intern nach jeder Operation immer in gekürzter Form gespeichert sein und der Nenner soll immer positiv sein. Beispielsweise `5/-15` soll als `-1/3` gespeichert werden. Falls der Bruch den Wert `0` annimmt, soll der Nenner den Wert `1` besitzen.
### Konstruktoren
### Konstruktoren
...
@@ -61,36 +61,34 @@ Folgende Operationen sollten auf jeden Fall implementiert werden, wobei der Copy
...
@@ -61,36 +61,34 @@ Folgende Operationen sollten auf jeden Fall implementiert werden, wobei der Copy
-`b1 = b2 + b3`
-`b1 = b2 + b3`
-`b2` und `b3` werden zusammenaddiert, ändern sich aber nicht
-`b2` und `b3` werden zusammenaddiert, ändern sich aber nicht
-`b1 = b2 += b3`
-`b3` wird direkt auf `b2` addiert
- das Ergebnis kann an `b1` zugewiesen werden
-`b1 = b2 + a`
-`b1 = b2 + a`
-`b2` und `a` werden zusammenaddiert, ändern sich aber nicht (`a` ist ein `int`!)
-`b2` und `a` werden zusammenaddiert, ändern sich aber nicht (`a` ist ein `int`!)
-`b1 = a + b3`
-`b1 = a + b3`
-`a` und `b3` werden zusammenaddiert, ändern sich aber nicht (`a` ist ein `int`!)
-`a` und `b3` werden zusammenaddiert, ändern sich aber nicht (`a` ist ein `int`!)
-`b1 = b2 += b3`
-`b3` wird direkt auf `b2` addiert
- das Ergebnis kann an `b1` zugewiesen werden
-`b1 = b2++`
-`b1 = b2++`
- post-increment
- post-increment
- in `b1` wird der alte Wert von `b2` geschrieben
- in `b1` wird der alte Wert von `b2` geschrieben
- anschließend wird `b2` um den Wert `1` erhöht
- anschließend wird `b2` um den Wert `1` erhöht
-`b1 = ++b2`
-`b1 = ++b2`
- pre-increment
- pre-increment
-`b2` wird um den Wert `1` erhöht
-`b2` wird um den Wert `1` erhöht
- das Ergebnis wird in `b1` geschrieben
- das Ergebnis wird in `b1` geschrieben
-`b1 = -b2`
-`b1 = -b2`
-`b1` wird das Negative von `b2` zugewiesen
-`b1` wird das Negative von `b2` zugewiesen
-`b2` bleibt unverändert
-`b2` bleibt unverändert
-`b1 = ~b2` (bitweiser Operator)
-`b1 = ~b2` (bitweiser Operator)
-`b1` wird der Kehrwert von `b2` zugewiesen
-`b1` wird der Kehrwert von `b2` zugewiesen
- der Nenner soll weiterhin positiv sein
- der Nenner soll weiterhin positiv sein
-`NullDivisionException` falls der Nenner `0` ist
-`NullDivisionException` falls der Nenner `0` ist
-`b2` bleibt unverändert
-`b2` bleibt unverändert
-`b1 = b2 /= b3`
-`b2` wird durch `b3` durchdividiert
-`NullDivisionException` falls durch `0` dividiert wird
- in diesem Fall soll der `NullDivisionException` kein Parameter übergeben werden
- das Ergebnis kann an `b1` zugewiesen werden
Alle weiteren arithmetischen Operatoren, wie beispielsweise `-`, `-=`, `--`, `*`, `/`... können analog implementiert werden.
Alle weiteren arithmetischen Operatoren, wie beispielsweise `-`, `-=`, `--`, `*`, `/`... können analog implementiert werden.
...
@@ -101,19 +99,14 @@ Folgende Operatoren sollten auf jeden Fall implementiert werden. `b1`, `b2` sind
...
@@ -101,19 +99,14 @@ Folgende Operatoren sollten auf jeden Fall implementiert werden. `b1`, `b2` sind
-`b1`
-`b1`
- ist genau dann `false` sein, wenn der Bruch den Wert `0` besitzt
- ist genau dann `false` sein, wenn der Bruch den Wert `0` besitzt
-**Wichtig! `int a = b1;` darf nicht gültig sein bzw. kompilieren. Daher ist das Schlüsselwort `explicit` zu verwenden.**
-**Wichtig! `int a = b1;` darf nicht gültig sein bzw. kompilieren. Daher ist das Schlüsselwort `explicit` zu verwenden.**
-`!b1`
-`!b1`
- ist genau dann `true` sein, wenn der Bruch den Wert `0` besitzt
- ist genau dann `true` sein, wenn der Bruch den Wert `0` besitzt
-`b1 == b2`
-`b1 == b2`
- ist genau dann `true`, falls `b1` und `b2` denselben Wert besitzen
- ist genau dann `true`, falls `b1` und `b2` denselben Wert besitzen
-`b1 != b2`
-`b1 != b2`
- ist genau dann `true`, falls `b1` und `b2` verschiedene Werte besitzen
- ist genau dann `true`, falls `b1` und `b2` verschiedene Werte besitzen
-`b1 < b2`
-`b1 < b2`
- ist genau dann `true`, falls `b1` echt kleiner als `b2` ist
- ist genau dann `true`, falls `b1` echt kleiner als `b2` ist
-`b1 <= b2`
-`b1 <= b2`
- ist genau dann `true`, falls `b1 < b2` oder `b1 == b2`
- ist genau dann `true`, falls `b1 < b2` oder `b1 == b2`
...
@@ -125,7 +118,7 @@ Diese Klasse stellt eine Exception dar und soll eine Fehlermeldung repräsentier
...
@@ -125,7 +118,7 @@ Diese Klasse stellt eine Exception dar und soll eine Fehlermeldung repräsentier
### Konstruktor
### Konstruktor
Weiters soll es genau einen Konstruktor geben, der als einzigen Parameter den Zähler des fehlerhaften Bruchs übergibt bekommt. Anschließend soll in `message_` die Fehlermeldung ```<nominator> / 0 - Dividing through 0 not valid!\n```, wobei `<nominator>` durch den übergebenen Parameter ersetzt werden soll. Der Copy-Konstruktor und der Copy-Assignment-Operator sollen gelöscht werden.
Weiters soll es zwei Konstruktoren geben. Einen der als einzigen Parameter den Zähler des fehlerhaften Bruchs übergibt bekommt. Anschließend soll in `message_` die Fehlermeldung `<nominator> / 0 - Dividing through 0 not valid!\n` gespeichert werden, wobei `<nominator>` durch den übergebenen Parameter ersetzt werden soll. Dieser Konstruktor soll aufgerufen werden, wenn ein fehlerhafter Bruch erstellt wird, beispielsweise auch bei der Kehrwertbildung. Der zweite Konstruktor soll keinen Parameter bekommen und nur die Fehlermeldung `Dividing through 0 not valid!\n` in `message_` speichern. Dieser Konstruktor soll genau dann aufgerufen werden, wenn durch einen Bruch mit dem Wert `0` dividiert wird. Der Copy-Konstruktor und der Copy-Assignment-Operator sollen gelöscht werden.
### Methoden
### Methoden
...
@@ -133,4 +126,4 @@ Außerdem soll in der Klasse genau eine Methode implementiert werden, nämlich d
...
@@ -133,4 +126,4 @@ Außerdem soll in der Klasse genau eine Methode implementiert werden, nämlich d
## Testprogramm
## Testprogramm
Ein kurzes Testprogramm, dass die wesentlichen Funktionalitäten überprüft steht bereits zur Verfügung. Die noch offenen Testcases werden in Kürze noch folgen.
Ein kurzes Testprogramm, das die wesentlichen Funktionalitäten überprüft, steht zur Verfügung.