Beispiel 4: ClRomZahl

28.11.2016 09:30 Uhr
#include <iostream>

using namespace std;
#include "rom4.h"

int main()
{
ClRomZahl zahl1, zahl2, ergebnis; 

cout << "Bitte geben Sie eine erste Zahl ein:";
zahl1.hole();
cout << "Bitte geben Sie eine zweite Zahl ein:";
zahl2.hole();

ergebnis.addiere(zahl1,zahl2);

cout << zahl1.druckbar() << " + " << zahl2.druckbar() << " = " << ergebnis.druckbar() << endl;
}

Beispiel 4: Erläuterungen I

#include <iostream>

using namespace std;
#include "rom4.h"

int main()
{
ClRomZahl zahl1, zahl2, ergebnis; 

1. Beobachtung:

Die Hinweise auf Implementationsdetails sind verschwunden.

Es steht ein Datentyp "ClRomZahl" zur Verfügung, der genauso verwendet
wird, wie int, char, float ...


2) Beobachtung:

Wir haben im Hauptprogramm keinerlei wie auch immer gearteten Hinweis
auf die Art und Weise, wie die Daten dargestellt werden.


cout << "Bitte geben Sie eine erste Zahl ein:";
zahl1.hole();

3) Beobachtung:

Alle Bearbeitungsschritte sind unsichtbar.


Gleichzeitig scheint die Syntax stark vereinfacht: wir rufen offensichtlich
Funktionen auf; daß diese "Adressen" haben, scheint aber nicht mehr wichtig zu
sein.

cout << "Bitte geben Sie eine zweite Zahl ein:";
zahl2.hole();

ergebnis.addiere(zahl1,zahl2);

cout << zahl1.druckbar() << " + " << zahl2.druckbar() << " = " << ergebnis.druckbar() << endl;
}

Beispiel 4: Erläuterungen II

#include <iostream>

using namespace std;
#include "rom4.h"

int main()
{
ClRomZahl zahl1, zahl2, ergebnis; 

Zu jeder Klasse (s. Headerhinweise) gibt es eine (implizit) vorhandene
Funktion, den sogenannten "Konstruktor", dessen Namen mit dem der Klasse
identisch ist.

Er ruft von sich aus "new" auf. 


cout << "Bitte geben Sie eine erste Zahl ein:";
zahl1.hole();
cout << "Bitte geben Sie eine zweite Zahl ein:";
zahl2.hole();

ergebnis.addiere(zahl1,zahl2);

cout << zahl1.druckbar() << " + " << zahl2.druckbar() << " = " << ergebnis.druckbar() << endl;
}

Beispiel 4: Erläuterungen zur Header-Datei

(Header-Datei im Anhang)


class ClRomZahl

Durch das Schlüsselwort 'class'  definieren wir eine 'Klasse
von Objekten'. 'class' hat eine ganz ähnliche Funktion, wie struct,
gruppiert also zusammengehörige, unterschiedliche Variablen und Funktionen zu
einer mit einer Bezeichnung ansprechbaren, größeren Einheit.
'class' ist jedoch wesentlich 'strenger' als 'struct': Wird eine
Informationseinheit als Klasse definiert, gibt es genau vorgeschriebene Wege,
wie damit gearbeitet werden kann - dies schützt den Programmierer vor vielen
möglichen Fehlerursachen.
Klassennamen sind streng genommen Variablennamen wie
alle anderen auch. Nachdem Sie aber so diszipliniert
verwendet werden müssen, empfiehlt es sich eine Namenskonvention zu wählen,
die sie auf den ersten Blick erkennbar macht. Innerhalb dieser Veranstaltung
wählen wir die Möglichkeit den Namen stets mit den beiden Buchstaben "Cl"
beginnen zu lassen.
    {
public:
Nur jene Variablen und / oder Funktionen einer Klasse, die nach dem
Schlüsselwort public: auftauchen, sind für den
Benutzer der Klasse (im Unterschied zu dem Programmierer, der sie erzeugt)
zugänglich.
Es ist weise, Klassen so zu schreiben, daß grundsätzlich nur Funktionen
öffentlich zugänglich sind, keine Variablen.
    void hole();
    char *druckbar();
    void addiere(ClRomZahl zahl1,ClRomZahl zahl2);
private:
Alle Mitglieder der Klasse, die nach dem Schlüsselwort private:

stehen, dürfen nur durch Funktionen benutzt werden, die Bestandteil der
Implementation der Klasse sind.
    char roemisch[20];
    int arabisch;
    void zuArabien();
    void zuRom();
    } ;

Terminologie:
Eine Variable in einer Klasse ist ein Element der Klasse.
Eine Funktion in einer Klasse ist eine Methode der Klasse.

Beispiel 4: Erläuterungen zur Bibliothek

(Bibliothek im Anhang; restliches Programm im Anhang)


#include <iostream>

using namespace std;
#include "rom4.h"

void ClRomZahl::addiere(ClRomZahl zahl1, ClRomZahl zahl2)
Wird in der Deklaration einer Funktion vor den eigentlichen
Funktionsnamen ein Klassenname, getrennt durch zwei Doppelpunkte, gesetzt,
so bedeutet dies: 'Diese Funkion ist Bestandteil der genannten Klasse'.
Solche Funktionen bezeichnet man als "Methoden" der Klasse.
Das bedeutet:
1) Die Funktion darf unter Angabe eines sie enthaltenten Objekts aufgerufen
werden.
eineZahl.addiere(zahl1,zahl2)
ist korrekt.
addiere(zahl1,zahl2)
wäre falsch!
{
arabisch=zahl1.arabisch+zahl2.arabisch;
2) Wird innerhalb einer zu einer Klasse gehörigen Funktion eine Variable
verwendet, deren Namen in der Deklaration der Klasse enthalten ist, so
handelt es sich um jene Variable, die zu dem Objekt gehört, von dem aus die
Klasse aufgerufen wurde.
Wenn wir den Aufruf
eineZahl.addiere(zahl1,zahl2)
voraussetzen, ist die obige Referenz also funktional äquivalent zu
eineZahl.arabisch

zuRom();
3) Wird innerhalb einer zu einer Klasse gehörigen Funktion eien andere zu ihr
gehörige Funktion aufgerufen, wird der name ohne Voranstellung eines
Objekts aufgerufen.
Wenn wir den Aufruf
eineZahl.addiere(zahl1,zahl2)
voraussetzen, ist die obige Referenz also funktional äquivalent zu
eineZahl.zuRom();
}

char *ClRomZahl::druckbar()
{

NUR DER PROGRAMMIERER EINER KLASSE HAT DAS RECHT IHRE
VARIABLEN ZU VERARBEITEN.
Deshalb muß für jede Variable die von einem Progrmam verarbeitet (oder
verändert) werden soll, eine Funktion bereitstehen, die dies ermöglicht.

return roemisch;
}

void ClRomZahl::hole()
{
cin >> roemisch;
zuArabien();
}

void ClRomZahl::zuArabien()
{
char roemischeZiffern[8] = "ivxlcdm";
int ziffernWert[7] = {1, 5, 10, 50, 100, 500, 1000};
int hilfe[10], stellen=0;

if (roemisch[0]=='0') return;

stellen=0;
for (int j; roemisch[stellen]!='\0'; stellen++)
    {
    for (j = 0; j < 7; j++)
        if (roemisch[stellen] == roemischeZiffern[j])
           {
           hilfe[stellen] = ziffernWert[j];
           break;
           }
    if (j == 7) return;
    }

for (int j=1; j < stellen; j++)
    if (hilfe[j] > hilfe[j-1])
       {
       hilfe[j] -= hilfe[j-1];
       hilfe[j-1] = 0;
       }

arabisch=0;
for (int j=0; j < stellen; j++) arabisch += hilfe[j];
}

void ClRomZahl::zuRom()
{
char roemischeZiffern[8] = "mdclxvi";
int ziffernWert[7] = {1000,500,100,50,10,5,1};
int stelle=0,hilfe;

hilfe=arabisch;
for (int i = 0; i < 7; i++)
    {
    while (hilfe >= ziffernWert[i])
          {
          roemisch[stelle] = roemischeZiffern[i];
          hilfe -= ziffernWert[i];
          stelle++;
          }
    }
roemisch[stelle]='\0';
}

Anhang: example4.zip

Schlagwörter: