zurück weiter

Eine Klasse erstellen
Ausgangspunkt DoubleArray

G.Eichelsdörfer
Staatliche Technikerschule Weilburg

In der Übung 6.3 sollte ein etwas informationsreicheres Datenfeld (arrayinfo) erstellt werden. Zu diesem Zweck ist eine Datenfeld-Komponente und zwei Ganzzahl-Komponenten in einem Verbund (Struct) zusammenzustellen.

struct DoubleArray
{
 int Size, Capacity;
 double Values[MaxSize];
};

Die Ganzzahlkomponente Size beinhaltet die Information, wie viele Elemente im Fließkommadatenfeld Values gültig sind. Die gültigen Elemente beginnen immer am Index 0 und liegen im Datenfeld lückenlos hintereinander. Die Komponente Capacity gibt an, wie viele Elemente das Datenfeld aufnehmen kann.

Dieser Struct bietet den Vorteil, dass das Datenfeld mit den Informationen über dieses Datenfeld in einem Verbund zusammengebunden sind. Wenn ein solcher Verbund an eine Funktion als Parameter übergeben wird, dann beinhaltet dieser Parameter alle erforderlichen Informationen über das Datenfeld.

Die Funktion append soll beispielsweise einem Datenfeld einen neuen Wert hinzufügen. Hierfür genügen zwei Parameter - einer vom Typ DoubleArray (s.o.) und ein zweiter, welcher den hinzuzufügenden Wert beinhaltet. Beachten Sie, dass die Funktion den DoubleArray-Parameter verändern muss. Dies kann sie nur, wenn sie das Original erhält. Somit muss der DoubleArray-Parameter per Referenz (&) importiert werden.

bool append(DoubleArray& Da, double Val)
{
 bool valid = Da.Size < Da.Capacity;
 if(valid) Da.Values[Da.Size++] = Val;
 return valid;
}

Obige Funktion ist sehr flexibel einsetzbar, weil ihr alle erforderlichen Daten in den Parametern zur Verfügung gestellt werden. Sie greift auf keine globale Konstante zu und schon gar nicht auf globale Variable. Sie ist schon ziemlich weitgehend wiederverwendbar, beispielsweise in anderen Projekten. Ein wesentliches Ziel beim Programmieren besteht darin, bereits erstellten Code (Funktionen, Klassen, ...) in anderen Zusammenhängen (Projekten) wiederverwenden zu können, damit "das Rad nicht immer wieder neu erfunden werden muss". Die Funktion append() erfüllt dieses Ziel bereits.

Es gibt aber noch ein paar Mängel:

  1. Die Kapazität des Datenfeldes ist fest im Verbundtyp (hier DoubleArray) verankert. Hier wäre eine Flexibilität zweckmäßig, welche die Festlegung der Datenfeldkapazität zur Laufzeit ermöglicht. Dazu ist Speicherallokation erforderlich, muss also noch aufgeschoben werden.

  2. Diejenige Funktion, welche eine Variable dieses Verbundtyps anlegt (hier main), muss die Initialisierung der Variablen durchführen. Dies ist zwar nicht ungewöhnlich, erfordert jedoch zwei, unten fettgedruckte, Anweisungen, die nicht vergessen werden dürfen - und, frei nach Murphy: "Wenn etwas vergessen werden kann, wird es irgendwann auch vergessen."
    const int MaxSize = 100;
    ...
    DoubleArray Werte;
    Werte.Size = 0;
    Werte.Capacity = MaxSize;

    Es ist eine automatisierte Initialisierung anzustreben, um die Programmiererin zu entlasten. Dies geht aber nicht ohne Vorarbeiten.

  3. Jede Funktion mit Zugriff auf eine DoubleArray-Variable kann deren Komponenten ändern, auch in einer unzulässigen Weise. So kann in der main-Funktion die Kapazität der DoubleArray-Variablen einfach 'mal auf 150 erhöht werden, ohne dass das Datenfeld tatsächlich über diese Kapazität verfügt. Damit wird die Datenkonsistenz verletzt, d.h. die Daten passen nicht mehr zusammen. Um dies zu verhindern sind die Zugriffsmöglichkeiten auf die DoubleArray-Komponenten einzuschränken. Wie? Das kommt noch.

Die Mängel sind erkannt, es bedarf also einiger Verbesserungen. Diese sind mit einer geeigneten Klasse erreichbar. Eine Klasse ist aus unserer Sicht eine Erweiterung eines Struct, genauer: eines Struct der Programmiersprache C (nicht C++) - nicht anders haben wir bisher Structs eingesetzt.

Ein solcher C-Struct bietet den vollen, ungeschützten Zugriff auf alle seine Komponenten und verfügt ausschließlich über (passive) Datenkomponenten. Funktionen, die mit seinen Daten arbeiten, gibt es in einem C-Struct nicht. Diese müssen, wie beim DoubleArray, außerhalb des Structs existieren und benötigen den Struct als Parameter.

Eine Klasse (C++, nicht in C) bietet geschützten Zugriff, Klassen-eigene Funktionen mit Zugriffsprivilegien und automatisierte Initialisierung ihrer Daten. Alles bestens also? Na ja, Verbesserungsbedarf ruft zumeist Lernbedarf hervor, so auch hier.