doppelt verkettete Listen
-
Hallo Leute, ich habe nach einem tutorial eine einfach verkettete liste geschrieben:
list.hclass LinkedList { public: LinkedList(); void push(int xPos, int yPos); void push(Raumschiff* r); void pop(); void first(); Raumschiff* first(int i); void show(); private: Raumschiff *pStart; };list.cpp
LinkedList::LinkedList() { pStart = NULL; } void LinkedList::push(int xPos, int yPos) { Raumschiff* pNew = new Raumschiff(GRUEN); pNew->setCoordinates(xPos,yPos); pNew->pNext = pStart; pStart = pNew; } void LinkedList::push(Raumschiff* r) { Raumschiff* pNew = r; pNew->pNext = pStart; pStart = pNew; } void LinkedList::pop() { if(pStart!=NULL) { Raumschiff* pOld = pStart; pStart = pStart->pNext; delete pOld; pOld = NULL; } } void LinkedList::first() { if(pStart!=NULL) pStart->zeige_werte(); } Raumschiff* LinkedList::first(int i) { if(pStart!=NULL) return pStart; } void LinkedList::show() { int counter = 1; Raumschiff* pTemp = pStart; while(pTemp!=NULL) { std::cout<<"Nummer: "<<counter<<std::endl; pTemp->zeige_werte(); pTemp = pTemp->pNext; ++counter; } }raumschiff.h
#ifndef Unit2H #define Unit2H #define LINKS 1 #define RECHTS 2 #define ROT 10 #define BLAU 11 #define GRUEN 12 class Raumschiff { public: Raumschiff(); Raumschiff(int Farbe); void starten(); void landen(); virtual void zeige_werte(); void setCoordinates(int newX, int newY); void SetAttributes(int energy, int direction); void SetColor(int Color); public: Raumschiff *pNext; Raumschiff *pPrev; private: int m_energie, m_richtung; int m_xCoord, m_yCoord; int m_Color; }; class Fregatte:public Raumschiff { public: Fregatte(); Fregatte(int Farbe); void schiessen(); void zeige_werte(); private: int m_raketen; };raumschiff.cpp
Raumschiff::Raumschiff() { m_Color = ROT; m_energie = 100; std::cout<<"Raumschiff erstellt: "; } Raumschiff::Raumschiff(int Farbe) { m_Color = Farbe; m_energie = 100; std::cout<<"Raumschiff erstellt mit Farbe"; if(Farbe == ROT) std::cout<<" Rot: "; if(Farbe== BLAU) std::cout<<" Blau: "; if(Farbe == GRUEN) std::cout<<" Gruen: "; } void Raumschiff::starten() { std::cout<<"Raumschiff startet"<<std::endl; } void Raumschiff::landen() { std::cout<<"Raumschiff landet"<<std::endl; } void Raumschiff::zeige_werte() { std::cout<<"Energie: "<<m_energie<<std::endl; std::cout<<"Richtung: "; if(m_richtung == LINKS) std::cout<<"links"<<std::endl; if(m_richtung == RECHTS) std::cout<<"rechts"<<std::endl; std::cout<<"Farbe: "; if(m_Color == ROT) std::cout<<"Rot"<<std::endl; if(m_Color == BLAU) std::cout<<"Blau"<<std::endl; if(m_Color == GRUEN) std::cout<<"Gruen"<<std::endl; } void Raumschiff::setCoordinates(int newX, int newY) { if(newX >= 0 && newX < 800 && newY >= 0 && newY < 600) { m_xCoord = newX; m_yCoord = newY; std::cout<<"Neue Position uebernommen"<<std::endl; } else { std::cout<<"Fehler: Koordinaten liegen ausserhalb des Bildschirms!"<<std::endl; } } void Raumschiff::SetAttributes(int energy, int direction) { m_energie = energy; m_richtung = direction; } void Raumschiff::SetColor(int Color) { m_Color = Color; } Fregatte::Fregatte() { m_raketen = 10; std::cout<<"Fregatte erstellt"<<std::endl; } Fregatte::Fregatte(int Farbe):Raumschiff(Farbe) { m_raketen = 10; std::cout<<"Fregatte mit Farbe erstellt"<<std::endl; } void Fregatte::schiessen() { if(m_raketen>0) --m_raketen; else std::cout<<"Keine Munition mehr"<<std::endl; } void Fregatte::zeige_werte() { Raumschiff::zeige_werte(); std::cout<<"Raketen: "<<m_raketen<<std::endl; }nun meine fragen:
wie baue ich dies zu einer doppelt verketteten list um?
welche methoden sollte eine list bieten?
wie kann ich meine push funktion so ausbauen, das sie "sicher" ein Raumschiff* entgegennimmt? (ist das push einer list eigentl dafür gedacht, ein objekt als parameter zu bekommen, welches in die liste eingetragen wird?)
-
kann mir keiner meine fragen beantworten?

-
sdsds schrieb:
kann mir keiner meine fragen beantworten?

Ja, ist schon komisch; bei anderen Threads purzeln die Antworten im Minuten-Tack und hier kommt nix. Vielleicht ist es zu viel Code bei einer zu wenig interessante Frage ...
sdsds schrieb:
wie baue ich dies zu einer doppelt verketteten list um?
Das ist nämlich einfach so, dass Du den Zeiger Raumschiff::pPrev bei push und pop einfach berücksichtigen musst. Ich habe die Stellen mit '//#' markiert
void LinkedList::push(Raumschiff* r) // push_front { Raumschiff* pNew = r; if( pStart ) //# { pStart->pPrev = pNew; } pNew->pNext = pStart; pNew->pPrev = 0; //# pStart = pNew; } void LinkedList::pop() // pop_front { if(pStart!=NULL) { if( pStart->pNext ) //# { pStart->pNext->pPrev = 0; } Raumschiff* pOld = pStart; pStart = pStart->pNext; delete pOld; pOld = NULL; } }Die erste Methode push(int xPos, int yPos) solltest Du entfernen. Das gehört nicht in die Liste. Mache statt desse besser einen eigenen Konstruktor für Raumschiff
class Raumschiff { public: Raumschiff(); Raumschiff(int Farbe); Raumschiff(int xPos, int yPos); //#Weiter solltest Du noch über den Destruktor, Copy-Konstruktor und Zuweisungs-Operator der LinkedList nachdenken. Was sagt Dein Tutorial dazu?
Und was steht in Deinen Tutorial zu Initialisierungslisten?sdsds schrieb:
welche methoden sollte eine list bieten?
siehe std::list<>
sdsds schrieb:
wie kann ich meine push funktion so ausbauen, das sie "sicher" ein Raumschiff* entgegennimmt?
Tut sie das nicht?
sdsds schrieb:
(ist das push einer list eigentl dafür gedacht, ein objekt als parameter zu bekommen, welches in die liste eingetragen wird?)
eigentlich push_back für das Anhängen am Ende der Liste und push_front für das Anhängen am Anfang.
Gruß
Werner
-
nein nicht sicher, da ich ja zeiger übergebe!
Wenn ich einen zeiger irgendwo erstelle, diesen übergebe, und dann den anderen lösche, verschwindet ja auch der in der liste oder?mein tutorial sagt nix weiter zu initialisierungslisten, auch über destr und copy konstr finde ich nix!
kannst du mir da etwas erklären? oder mir ein gutes tutorial zu dem thema empfehlen?
-
Wenn Du es "sicher" haben willst, dann musst Du eine Kopie in die Liste tun.
Geht in etwa so:void LinkedList::push(Raumschiff* r) { Raumschiff* pNew = new Raumschiff(*r); pNew->pNext = pStart; pStart = pNew; }Dazu brauchst Du natuerlich einen Copy-Constructor. Siehe z.B. hier http://www.fredosaurus.com/notes-cpp/oop-condestructors/copyconstructors.html