Verkettete Listen
-
Hallo,
in meinem Buch wird das Thema Verkettete Listen OO verdeutlicht. Hier mal die Klassendefinitionen:class Knoten { public: Knoten() {} virtual ~Knoten() {} virtual Knoten* einfuegen( Daten* d ) = 0; virtual void anzeigen() = 0; }; class AllgemeinerKnoten : public Knoten { private: Daten* daten; Knoten* next; public: // Konstruktor AllgemeinerKnoten( Daten* d, Knoten* n ): daten(d), next(n) { // Zu Debug- bzw. Verständniszwecken ggf. entfernen cout << "Objekt [AllgemeinerKnoten] erzeugt\n"; } // Destruktor ~AllgemeinerKnoten() { delete next; delete daten; } // Implizit virtual Knoten* einfuegen( Daten* d ); // Implizit virtual void anzeigen(); }; class EndKnoten : public Knoten { public: EndKnoten() { // Zu Debug- bzw. Verständniszwecken ggf. entfernen cout << "Objekt [EndKnoten] erzeugt\n"; } ~EndKnoten() {} // Implizit virtual Knoten* einfuegen( Daten* d ); // Implizit virtual void anzeigen() { }; }; private: // ... zeigt immer auf das erste Element Knoten* next; public: // Konstruktor AnfangsKnoten() { // ... gleich auch einen Endknoten erzeugen next = new EndKnoten; // Zu Debug- bzw. Verständniszwecken ggf. entfernen cout << "Objekt [AnfangsKnoten] erzeugt\n"; } ~AnfangsKnoten() {} // Implizit virtual Knoten* einfuegen( Daten* d ); // Implizit virtual void anzeigen(); }; class Liste { private: AnfangsKnoten *anfang; public: // Bei Anlegen gleich ein Objekt "Anfangsknoten" erzeugen // Der Konstruktor von "AnfangsKnoten" erzeugt wiederum // ein Objekt "EndKnoten", auf das dieser gleich zeigt. Liste() { anfang = new AnfangsKnoten; } ~Liste() { delete anfang; } void einfuegen( Daten* d ) { anfang->einfuegen(d); } void alles_anzeigen() { anfang->anzeigen(); } };Die Methoden habe ich jetzt mal weggelassen.
Das ganze Funktioniert im Prinzip so:
Anfangsknoten<->AllgemeinerKnoten<->---<->AllgemeinerKnoten<->EndknotenMein Problem ist jetzt Der Destruktur von Alg.Knoten löscht jeweils den nächsten, auf den er zeigt. Also der Letzte AlgKnoten den Endknoten etc. Der Anfangsknoten wird von der Liste gelöscht. Nur wie wird der erste allgemeine Knoten in der Liste gelöscht?
Viele Grüße
-
da fehlt dem Anfangsknoten wohl auch ein delete nex; im Destruktor.
-
Gut hätte ich auch gesagt. Der Fehler wird aber auch in den folgenden Kapiteln, die darauf aufbauen nicht behoben.
Dann noch eine Frage in einem späteren Kapitel wird an dem Beispiel das Arbeiten mit Templates verdeutlicht.
Da werden alle Knoten Klassen mit Templates ausgestattet. Aber hätte man nicht einfach die Klasse Daten, in der die Werte gespeichert sind mit Templates ausstatten können?
-
Tom2 schrieb:
Aber hätte man nicht einfach die Klasse Daten, in der die Werte gespeichert sind mit Templates ausstatten können?
Hätte man, aber dazu hätte man dann immernoch das Klassentemplate Daten überall mit rumschleppen müssen, jedesmal ein neues Daten<X> erstellen müssen bevor man es in die Liste hängt usw. Dann lieber gleich die ganze Liste zum Template machen und die Elemente direkt da reinhängen.
-
Dazu noch eine Frage zu den Templates. Dort steht so ungefähr folgender Code:
template <class T> void input( Liste<T>& data ) { input_func( data ); } ... void input_func( Liste<Temperatur>& tempList ) { ... void input_func( Liste<Daten>& datenList ) { ...Ist die Funktion input nicht total sinnlos? Man könnte doch gleich input_func in func umbenennen. Das hätte doch durch die Überladung genau den gleichen Effekt. Zumal die Überladung in func ohnehin genutzt wird.
-
Kann mir da keiner weiterhelfen, und sagen, ob ich richtig lag?
-
Wenn in deinen weggeschnittenen Stellen nicht zusätzliche Informationen versteckt waren: ja.
Ansonsten:
Geht es in dem Kapitel um Refactoring und wie man trotz neuer Methodennamen auch noch die alte API supported?
Handelt es sich da um freie Funktionen oder Methoden einer Klasse?
Ist da irgendwas abgeleitet und in der Basisklasse war input_func virtual?
Oder IST das eine Basisklasse und in der Klassendefinition ist input_func als virtual deklariert?
Welches Buch ist das?
-
Hier komplett:
// main.cpp #include "daten.h" #include "temperatur.h" #include "lliste.h" void input_func( Liste<Temperatur>& tempList ); void input_func( Liste<Daten>& datenList ); template <class T> void input( Liste<T>& data ); int main( void ) { // Instantiierung Liste<Temperatur> elemente1; Liste<Daten> elemente2; input(elemente1); // Liste<Temperatur> input(elemente2); // Liste<Daten> elemente1.alles_anzeigen(); elemente2.alles_anzeigen(); return 0; } // Funktion zum Einlesen der Eigenschaften für Temperatur void input_func( Liste<Temperatur>& tempList ) { Temperatur* daten; int grad; char monat[20]; for(;;) { cout << "Monat eingeben : "; if( (!(cin >> monat)) ) strcpy( monat, "keine Angabe"); cout << "Temperatur eingeben (99=Ende) : "; if( (!(cin >> grad)) || grad == 99 ) break; // Ende daten = new Temperatur(grad, monat); tempList.einfuegen(daten); } } // Funktion zum Einlesen der Eigenschaften für Daten void input_func( Liste<Daten>& datenList ) { Daten* daten; int iwert; for(;;) { cout << "Wert eingeben (0=Ende) : "; if( (!(cin >> iwert)) || iwert == 0 ) break; // Ende daten = new Daten(iwert); datenList.einfuegen(daten); } } // Funktions-Template template <class T> void input( Liste<T>& data ) { input_func( data ); }Buch: C++ von A bis Z