Template Class - List



  • Hey Leute,
    ich muss fürs Studium bei fast jeder Aufgabe eine Liste programmieren und wollte sie nun gleich als Template implementieren. Das ganze läuft auch schon perfekt, allerdings habe ich ein riesen Problem.

    Zur Zeit verwaltet die Liste Pointer auf die Element Struktur:

    template<typename T>
    	struct __declspec(dllexport) Element 
    	{
    		Element<T> *prev;
    		Element<T> *next;
    
    		T *element;
    	};
    

    Wenn ich nun eine Liste erstelle, bsp. new List<int>, dann wird mir eine Liste erstellt, die mir Zeiger auf Integer verwaltet. Ich hab es im Moment so implementiert, dass die Liste immer nur Zeiger verwaltet.

    Der Destruktor der Liste sieht folgendermaßen aus:

    Element<T> *ptr = this->head;
    
    		while(ptr)
    		{
    			Element<T> *buffer = ptr;
    			ptr = ptr->next;
    			delete buffer->element;
    			delete buffer;
    		}
    

    Jetzt möchte ich meine Liste jedoch auch kompatibel für die Verwaltung von Integern machen. Das Problem ist, dass das Struktur-Element dann nicht den Zeiger, sondern den direkten Wert verwalten müsste. Das führt bei mir im Destruktor der Liste dann jedoch zu dem Fehler, dass ich kein delete auf einen Nicht-Zeiger ausführen darf. Wenn ich jedoch Klassen verwalte muss ich sie als Referenz speichern, und das delete buffer->element ist nötig, damit der Destruktor der Klasse aufgerufen wird, die in der Liste verwaltet wird.

    Muss ich eine zweite Liste implementieren, eine für Zeiger und eine für konstante Werte oder was empfielt ihr mir?

    Grüße Kromat



  • Wenn ich jedoch Klassen verwalte muss ich sie als Referenz speichern

    Nein? Klassen kannst du auch als "T element" speichern. Dann wird der Destruktor automatisch aufgerufen.



  • Meinst du so?

    ListenElement:

    template<typename T>
    	struct __declspec(dllexport) Element 
    	{
    		Element<T> *prev;
    		Element<T> *next;
    
    		T element;
    	};
    

    ListenDestruktor:

    Tmp List<T>::~List()
    	{
    		Element<T> *ptr = this->head;
    
    		while(ptr)
    		{
    			Element<T> *buffer = ptr;
    			ptr = ptr->next;
    			delete buffer;
    		}
    	}
    

    Und beim erstellen der Liste:

    int main()
    {
    List<MeineKlasse> *Liste = new List<MeineKlasse>();
    Liste->insertLast(MeineKlasse(Parameter));
    }
    

    Kann ich die Klasse jetzt per Gleichheitszeichen dem "T element" der ListenElementStruktur zuordnen oder muss ich memcpy nutzen?

    Ist diese Methode zu empfehlen oder ist sie sehr langsam? Bei Funktionsaufrufen übergibt man ja Arrays auch als Referenz und Klassen können ja auch einen sehr großen Inhalt haben.

    Edit:
    Und in der Funktion in der ich folgende Zeile aufrufe:

    List<MeineKlasse> *Liste = new List<MeineKlasse>();
    Liste->insertLast(MeineKlasse(Parameter));
    

    Wenn die Funktion vorbei ist würde ja auch schon der Destruktor von der Klasseninstanz aufgerufen werden die ich gerade als Flache Kopie in die Liste gehauen hätte. Dann wär die Flache Kopie zwar noch da, aber die Zeiger der Klasse die beim erstellen schon initialisiert worden wären, würden schon auf keinen Inhalt mehr zeigen weil der bereits deleted wurde



  • Wenn du keine flache Kopie haben willst, musst du den Copyoperator eben so definieren, dass erst nicht flach kopiert. 🙄


Anmelden zum Antworten