Öffentlichkeit und Privatsphäre |
So wie in einer Funktion lokale Variable nach außen unsichtbar sind, können in einer Klasse Datenelemente und Elementfunktionen verborgen werden, die nur für den internen Bedarf gedacht sind. Diese Elemente sind privat. Auf private Elemente können alle Elementfunktionen frei zugreifen. Dadurch ist jeder Zugriff auf sie kontrollierbar. Die öffentlichen Elementfunktionen bestimmen, wie die privaten Datenelemente geändert werden können und welche Abläufe dazu notwendig sind.
[Bruchrechnung mit privaten Daten]
class tBruch
{
public:
tBruch() {zaehler=0; nenner=1;}
long GetNenner() {return nenner;}
long GetZaehler() {return zaehler;}
void SetNenner(long p) {if (p!=0) nenner=p;}
void SetZaehler(long p) {zaehler=p;}
void Show();
private:
long zaehler;
long nenner;
};
void tBruch::Show()
{
cout << zaehler << "/" << nenner << endl;
}
int main()
{
tBruch bruch;
long inNenner, inZaehler;
cout << "Zähler Leerzeichen Nenner eingeben!" << endl;
cin >> inZaehler >> inNenner;
bruch.SetNenner(inNenner);
bruch.SetZaehler(inZaehler);
bruch.Show();
}
Im Beispiel der Klasse tBruch sind die Datenelemente zaehler und nenner privat. Der Zugriff erfolgt durch die Funktionen, die mit >>Get<< oder >>Set<< beginnen. Auf diese Weise lässt sich verhindern, dass jemand den Nenner auf 0 setzt. Auch können Sie bei Änderungen oder vor Ausgaben den Bruch automatisch kürzen. Auch bei der Datumsklasse kann es durchaus sinnvoll sein, einen direkten Zugriff der Datenelemente zu verhindern. So können Sie leicht verhindern, dass als Monat 13 oder 0 angegeben wird. Aber die Möglichkeiten gehen über die einfachen Konsistenzprüfungen hinaus. Vielleicht soll auch der Wochentag Bestandteil des Datums werden. Damit der Wochentag nicht bei jeder Anfrage neu berechnet werden muss, kann man ihn in einer privaten Elementvariablen vorhalten. Dann muss aber sichergestellt sein, dass das Datum nicht direkt geändert wird. Werden Datumsänderungen aber durch entsprechende Funktionen durchgeführt, dann kann bei jeder Änderung der Wochentag für ungültig erklärt werden. Wenn er angefordert wird, schaut die Funktion nach, ob er neu berechnet werden muss.
[Klasse mit privaten Elementen]
class tDatum
{
private:
int tag;
int monat;
int jahr;
int wochentag;
public:
tDatum();
virtual ~tDatum();
void setTag(int Wert);
void setMonat(int Wert);
void setJahr(int Wert);
int getTag() {return tag;}
int getMonat() {return monat;}
int getJahr() {return jahr;}
int getWochentag();
};
tDatum::tDatum()
{
wochentag = -1;
}
void tDatum::setMonat(int Wert)
{
if (Wert>0 && Wert<13 && monat!=Wert) {
monat = Wert;
wochentag = -1;
}
}
Damit jeder, der die Klasse benutzt, daran denkt, bei Änderungen die Elementvariable wochentag auf -1 zu setzen, werden die Elementvariablen tag, monat und jahr als privat deklariert. Damit sind sie dem Zugriff von außen entzogen. Sie können nur über die Elementfunktionen geändert werden. So sorgt die Elementfunktion setMonat() dafür, dass einerseits kein ungültiger Monat in das Objekt eingetragen werden kann. Gleichzeitig sorgt sie auch dafür, dass der Wochentag ungültig wird, sobald sich der Monat ändert. Auf diese Weise wird erreicht, dass die Elementfunktion getWochentag() den Wochentag ohne Neuberechnung zurückgeben kann, sofern sie nicht von einer der Änderungsfunktionen auf -1 gesetzt wurde. Nur dann muss der Wochentag neu berechnet werden.
[Implementation eines Stacks (stack.cpp)]
// Programm zur Demonstration einer Stack-Klasse
#include <iostream>
using namespace std;
// Knoten einer verketteten Liste
class tNode
{
public:
int d; // Daten, hier ganze Zahlen
tNode *next; // Verkettung
};
// Der Stack als Verbindung aus Anker und Operationen
class tStack
{
public:
tStack();
~tStack();
void push(int); // fügt Informationen hinzu
int pop(); // holt Informationen heraus
private:
tNode * Anker; // jeder Stack hat seinen eigenen Anker
};
tStack::tStack()
{
Anker = 0; // leere Liste wird vorbereitet
}
// Der Destruktor löscht alle übriggebliebenen Elemente
tStack::~tStack()
{
tNode *last = Anker; // Hilfszeiger zum Sichern des Ankers
while (Anker) // solange noch Elemente in der Liste
{
last = Anker; // erstes Element sichern
Anker = Anker->next; // Anker auf zweites Element setzen
delete last; // erstes Element freigeben
}
}
// Neues Element vorn in die Liste einhängen
void tStack::push(int d)
{
tNode *node = new tNode; // erzeugt Listenelement
node->d = d; // besetzt das Datenfeld
node->next = Anker; // hänge bisherige Liste an
Anker = node; // Mache dieses Element zum Anker
}
// Oberstes Element auslesen und aus der Liste löschen
int tStack::pop()
{
int inhalt=0; // Hilfsvariable vom Typ der Elementdaten
if (Anker) // sofern die Liste nicht schon leer ist
{
tNode *old = Anker; // sichere erstes Element
Anker = Anker->next; // setze Anker auf zweites Element
inhalt = old->d; // kopiere den Knoteninhalt
delete old; // Ausgelesenen Knoten freigeben
}
return inhalt; // liefere den Knoteninhalt
}
// Hauptprogramm zum Testen des Stacks
int main()
{
tStack stack; // lege einen Stack an
stack.push(2); // schiebe Testdaten darauf
stack.push(5);
stack.push(18);
cout << stack.pop() << endl; // lese den Stack aus
cout << stack.pop() << endl;
cout << stack.pop() << endl;
}
[Freundliche Klasse (friend.cpp)]
class Kumpel;
class Polizei
{
public:
void hilf(Kumpel&);
};
// Damit die Klasse Kumpel die Klasse in der Schnittstelle
// benutzen kann muss die Klasse Kollege hier deklariert werden
class Kollege;
class Kumpel
{
private:
int geheim;
void spionieren();
friend void hilf(Kumpel);
friend class Kollege;
friend void Polizei::hilf(Kumpel&);
};
class Kollege
{
public:
Kollege()
{
JB.geheim=007;
}
Kumpel JB;
};
void hilf(Kumpel Egon)
{
Egon.spionieren();
}
Die Klasse Kumpel hat drei friend-Deklarationen: Die erste erlaubt der Funktion hilf(), auf alle Elemente zuzugreifen. In der zweiten Deklaration wird die Klasse Kollege zum Freund. Damit darf jede Elementfunktion der Klasse Kollege beliebig auf Elemente von Kumpel zugreifen. Die dritte Deklaration erlaubt es, dass von der Klasse Polizei nur die Elementfunktion hilf() auf alle Elemente der Klasse Kumpel zugreifen darf. Alle anderen Elementfunktionen der Klasse Polizei dürfen dies nicht.
|
Diese Seite basiert auf Inhalten aus dem Buch
Arnold Willemer: Einstieg in C++ Mit freundlicher Genehmigung und Unterstützung des Verlags galileo computing |
| Informatik-Ecke Einstieg in C++ |
(C) Copyright 2005 Arnold Willemer
|