Lektion 60:

Die Klasse Vector

 Die Klasse Vector soll sich so verhalten wie ganz normale Arrays auch. Weil es zunächst recht ungewohnt ist, Template-Klassen zu schreiben, soll die Klasse Vector so angelegt werden, daß sie double-Werte verwaltet. Das Umwandeln in eine Template-Klasse kann zum Schluß geschehen.

Sicher braucht die Vector-Klasse als Attribute einen Zeiger auf ein dynamisch angelegtes Array und einen int, der die Größe des Arrays angibt.

class Vector
{
private:
   double *m_data;
   int m_size;
};

Im Konstruktor soll dieses Array mit new angelegt werden, und im Destruktor wird es wieder gelöscht.

   Vector(int size)
   {
      m_size=size;
      m_data=new double[m_size];
   };
   ~Vector()
   {
      delete[] m_data;
   };

Sinnvoll ist auch eine Methode, welche die aktuelle Größe des Arrays zurückgibt.

   int getSize()
   {
      return m_size;
   };

Und der Kern der Vector-Klasse liegt im geschickt überladenen operator[]. Dieser Operator muß einfach nur das Element an der Position zurückgeben, die als Index in den eckigen Klammern übergeben wurde.

   double operator[](int index)
   {
      return m_data[index];
   };

Damit funktioniert jetzt schon folgendes Programm:

#include <iostream>
using namespace std;

class Vector
{
private:
   double *m_data;
   int m_size;
public:
   Vector(int size)
   {
      m_size=size;
      m_data=new double[m_size];
   };
   ~Vector()
   {
      delete[] m_data;
   };
   double operator[](int index)
   {
      return m_data[index];
   };
   int getSize()
   {
      return m_size;
   };
};

void main()
{
   Vector v(10);
   cout<<v[5];
};

Hingegen geht folgendes nicht:

void main()
{
   Vector v(10);
   v[5]=4711;
   cout<<v[5];
};

Der Compiler gibt folgende Fehlermeldung aus:

error: '=' : left operand must be l-value

 Das ist eine Fehlermeldung, der Sie bestimmt noch öfter begegnen werden. Sie besagt, daß die Zuweisung nicht funktioniert, weil der linke Wert kein L-Wert ist. Ein L-Wert ist ein Wert, der auf der linken Seite einer Zuweisung stehen darf. Zum Beispiel sind Variablen immer L-Werte, während einfache Zahlen keine L-Werte sind.

int anzahl;
anzahl=5;// funktioniert
7=5;// funktioniert nicht
5=anzahl;// funktioniert auch nicht

Beachten Sie auch hier wieder, daß die Zuweisung in C++ nicht als Gleichung wie in der Mathematik verstanden werden darf. Sie ist einfach nur eine Zuweisung.

Auch Referenzen auf L-Werte sind wiederum L-Werte.

int anzahl;
int &ra=anzahl;
ra=5;// funktioniert

Der Wert

m_data[index]

ist ein L-Wert, denn man könnte schreiben:

m_data[index]=5;

Aber die Rückgabe einer Funktion ist normalerweise kein L-Wert. Es hätte zum Beispiel keinen Sinn,

v.getSize()=5;

zu schreiben.

 Sie können die Rückgabe einer Funktion aber zu einem L-Wert machen, indem Sie einfach eine Referenz auf einen L-Wert übergeben.

   doubleoperator[](int index)
   {
      return m_data[index];
   };

Jetzt funktioniert

void main()
{
   Vector v(10);
   v[5]=4711;
   cout<<v[5];
};

Die Klasse Vector sieht schon fast fertig aus. Daß sie so klein ist, hat wenig zu sagen. Gute Klassen sind oft sehr klein. Ein kleines Extrabonbon sollte man aber unbedingt noch einbauen: eine Überprüfung der Array-Zugriffe, daß der Index nicht außerhalb des erlaubten Bereichs liegt. Sehr viele Programmierfehler lassen sich nämlich auf falsche Array-Zugriffe zurückführen. Mit der neuen Vector-Klasse wird das zwar immer noch passieren, aber Sie bemerken den Fehler wenigstens und können ihn dann beheben.

   doubleoperator[](int index)
   {
      assert(index>=0);
      assert(index<m_size);
      return m_data[index];
   };

Übung:

Für die spätere Verwendung dieser Klasse wird eine Methode sinnvoll sein, die das Array vergrößern kann.

   void grow(int newSize)

Diese Methode legt ein neues Array der neuen Größe an, kopiert dann alle Werte des alten Arrays in das neue Array, löscht das alte Array und setzt dann die Attribute m_size und m_data auf die neuen Werte.

Schreiben Sie diese Methode!

Einsendungen:

Musterlösung


Falls Ihnen Fehler im Text auffallen oder Sie Verbesserungsvorschläge haben, dann schicken Sie mir bitte eine Mail. Ich werde mich dann sofort darum kümmern.
[aktuelle Version] [inhalt] [index]      [Fehlerkorrektur, Verbesserungsvorschlag]

© Volkard Henkel <volkard@normannia.de>, last update: 08/25/00