home *** CD-ROM | disk | FTP | other *** search
- #pragma +
- // Objektorientiertes Telefonlisten-Programm
- //
- // mit generischen Listenklassen
- //
- // Jens Gelhar 03.02.91
-
-
- #include <stream.h>
- #include <string.h>
-
-
- // * * * abstrakter Datentyp "Listenelement" * * *
-
- class Listenelement
- { private:
- Listenelement *next, *prev; // Vorgänger und Nachfolger
-
- virtual int compare(const Listenelement*) const = 0;
- // vergleicht Objekt "*this" mit einem anderen Listenelement
- // und gibt -1, 0 oder +1 zurück (wie bei "strcmp")
-
- virtual void ausgabe() const = 0;
- // Ein Listenelement ausgeben
-
- virtual ~Listenelement()
- { }
- // virtuieller Destruktor - hier nur ein Dummy, kann aber
- // in abgeleiteten Klassen überdeckt werden
-
- protected:
- // kleine Extras: abgeleitete Klassen dürfen "next" und "prev"
- // auslesen:
- Listenelement *getnext() const
- { return next; }
- Listenelement *getprev() const
- { return prev; }
-
- friend class Liste; // Diese später deklarierte Klasse
- // braucht Zugriff auf private Member
- };
-
-
- // * * * generischer Datentyp "Liste" * * *
-
- class Liste
- { private:
- Listenelement *anfang, *ende; // erstes und letztes Element
- // der Liste
- protected:
- void insert(Listenelement *neu);
- // sucht eine geeignete Position für das Element "*neu" und
- // hängt es in die Liste ein
-
- public:
- Liste(); // Konstruktor zur Initialisierung
- ~Liste(); // Destruktor (löscht alle
- // Listenelemente)
- void ausgabe(); // gibt die ganze Liste aus
-
- Listenelement *suchen(Listenelement *);
- // sucht ein Element, das dem Argument-Element "entspricht"
- // (was immer das in einer konkreten Liste heißen mag -
- // jedenfalls ein Element, bei dem "compare" Null liefert)
- // oder Null, wenn kein solches element existiert.
-
- void loeschen(Listenelement*);
- // hängt ein Element aus der Liste aus und löscht es
- // mit "delete"
- };
-
- Liste::Liste()
- { anfang = 0;
- ende = 0;
- }
-
-
- Liste::~Liste()
- {
- Listenelement *p = anfang;
-
- while(p)
- { Listenelement *hilf = p;
- p=p->next;
- delete hilf;
- }
- }
-
-
- void Liste::ausgabe()
- { for(Listenelement *l = anfang; l; l = l->next)
- l->ausgabe();
- }
-
- Listenelement *Liste::suchen(Listenelement *e1)
- { for(Listenelement *e2 = anfang;
- e2 && e2->compare(e1);
- e2 = e2->next);
- return e2;
- }
-
-
- void Liste::insert(Listenelement *neu)
- {
- // Position suchen:
- Listenelement *pos = anfang;
- while (pos && neu->compare(pos) > 0)
- pos = pos->next;
-
- // Element an Position "pos" in Liste einfügen
- // (prinzipiell genau wie in der ersten Programmversion)
-
- if (pos == 0)
- // Sonderfall: Anfügen an das Ende der Liste
- {
- Listenelement *alt = ende; // altes Listenende
-
- if (alt != 0)
- // allgemeiner Unter-Fall: wirklich anhängen
- {
- alt->next = neu;
- neu->prev = alt;
- neu->next = 0;
- ende = neu;
- }
- else
- // spezieller Spezialfall: Liste ist noch leer
- { neu->next = 0;
- neu->prev = 0;
- anfang = neu;
- ende = neu;
- }
- }
- else
- if (pos->prev == 0)
- // Sonderfall: Neues Element an Listenanfang hängen
- {
- pos->prev = neu;
- neu->next = pos;
- neu->prev = 0;
- anfang = neu;
- }
- else
- // allgemeiner Fall: Element in Liste einhängen
- {
- Listenelement *vor = pos->prev;
- // "neu" zwischen "vor" und "pos" einhängen:
- vor->next = neu;
- neu->prev = vor;
- neu->next = pos;
- pos->prev = neu;
- }
- }
-
-
- void Liste::loeschen(Listenelement *E)
- // Löscht das Element, auf das "E" zeigt, aus der Liste
- {
- // Vorgänger unf Nachfolger des zu löschenden Elements
- Listenelement *vor = E->prev, *nach = E->next;
-
- if (vor)
- // Element hat Vorgänger: Dann dessen Nachfolger umsetzen
- vor->next = nach;
- else
- // kein Vorgänger: Dann Listenanfang aktualisieren
- anfang = nach;
-
- if (nach)
- // Element hat Nachfolger: Dann dessen Vorgänger verändern
- nach->prev = vor;
- else
- // kein Nachfolger, also Listenende anpassen
- ende = vor;
-
- delete(E);
- }
-
-
-
- // * * * spezieller Datentyp "Eintrag" * * *
-
- class Eintrag : public Listenelement
- { public:
- char name[30]; // Name und...
- char nummer[20]; // Telefonnummer
-
- // Konstruktor:
- Eintrag(const char *neuname, const char *neunummer);
-
- // Funktionen, die virtuelle Funktionen der Basisklasse
- // definieren:
- int compare(const Listenelement*) const;
- void ausgabe() const;
- };
-
-
- Eintrag::Eintrag(const char *neuname, const char *neunummer)
- : name(neuname),
- nummer(neunummer)
- { }
-
-
- int Eintrag::compare(const Listenelement* that) const
- {
- Eintrag *that2 = (Eintrag*) that;
- return strcmp(this->name, that2->name);
- }
-
-
- void Eintrag::ausgabe() const
- { cout << name << ": " << nummer << "\n"; }
-
-
- // * * * spezieller Datentyp "Telefonbuch" * * *
-
- class Telefonbuch : private Liste
- { public:
- // Neues Element erzeugen und einfügen:
- Eintrag *insert(const char *, const char *);
-
- // Element anhand des Namens suchen:
- Eintrag *suchen(const char *);
-
- // zwei Funktionen werden öffentlich vererbt:
- Liste::ausgabe;
- Liste::loeschen;
- };
-
-
- Eintrag* Telefonbuch::insert(const char *neuname, const char *neunummer)
- {
- // neues Element erzeugen:
- Eintrag *neu = new Eintrag (neuname, neunummer);
-
- if (!neu) return 0; // kein Speicher frei!
-
- // Element in Liste einhängen:
- Liste::insert(neu);
-
- // Fertig, Zeiger auf neues Element zurückgeben:
- return neu;
- }
-
-
- Eintrag *Telefonbuch::suchen(const char *name)
- {
- Eintrag dummy(name,"");
- return (Eintrag*) Liste::suchen(&dummy);
- };
-
-
- // * * * Hauptprogram * * *
-
- void main()
- {
- // Eine Liste wird deklariert und initialisiert:
-
- Telefonbuch t;
-
- // Ein paar Beispieldaten werden eingefügt:
-
- t.insert("Harley-Davidson", "001-414/342-4680");
- t.insert("Boris Becker", "0815/4711");
- t.insert("James Bond", "007/26731");
- t.insert("Maxon", "06196/481813");
- t.insert("Zaphod Beeblebrox", "00042/08154242");
- t.insert("Luxemburg", "00352");
- t.insert("Queensr\0377che", "795069");
- t.insert("Fishbone", "4676152");
-
- // Ein Datensatz wird gesucht und ggf. gelöscht:
-
- Eintrag *e = t.suchen("Maxon");
- if (e)
- t.loeschen(e);
- else
- cout << "Name nicht gefunden!\n";
-
- // restliche Liste ausgeben:
- t.ausgabe();
-
- // Löschen der Liste geschieht automatisch durch Destruktor-Aufruf
- }
-
-
-