Klassen - Objekte - Zeiger und Listen
-
Hi - habe ein bisschen gesucht und durchgelesen aber bei meinem Problem bin ich nicht wirklich weiter gekommen.
Ich habe zwei Klassen, die ich erstellen möchte. Die eine erstellt Items, die andere soll dieses verwalten.
Immer, wenn ich eine Klasse erstelle, speichere ich das Objekt in einer Liste. (hatte dort erst auch nur einen pointer gespeichert) - nunja.. Jetzt möchte ich aus der Liste das Objekt raussuchen und dann über die Item-Klasse löschen.
class A{ list<Item> spiele = list<Item>(); void addSpiel(string titel, int sZahl, int alter){ pointer = new Item(titel, sZahl, alter, id); spiele.push_back(*pointer); } bool entferneItem(int id){ for(auto i = spiele.begin(); i != spiele.end(); i++){ if(*i->getID() == this->id){ delete *i; spiele.erase(i); return true; } return false; }
Jetzt bekomme ich folgende Fehlermeldung :
error: cannot delete expression of type 'std::_List_iterator<Item>'
delete i;Ich habe das ganze aber auch probiert über pointer .. aber verstehe nicht ganz wieso es nicht funktioniert. Mein Gedanke ist/war, dass durch auto i hier automatisch den Datentyp des Objekts übernimmt und dann dieses Objekt löscht. Oder muss ich doch komplett umbauen, darf gar keine Objekte in der Liste speichern, sondern nur zeiger?
Danke für jede Hilfe
bobbgott
-
Warum nutzt du überhaupt Pointer? Du hast doch eine
list<Item>
, also eine Liste von Items, nicht eine Liste von Item-Pointern! Kommst du aus einer anderen Sprache, wo man alle Objekte mitnew
anlegen muss? In C++ ist das nicht der Fall. Du kannst du einItem
ohne Pointer anlegen.Lösche das
new
und auch dasdelete
vollständig aus deinem Code.
Das addSpiel wird:Item item(titel, sZahl, alter, id); spiele.push_back(item)
oder direkt
spiele.emplace_back(titel, sZahl, alter, id);
Noch 3 andere Dinge:
- Was ist das
this->id
in Zeile 11 (if(*i->getID() == this->id){
)? Willst du nicht lieber mit dme Parameterid
vergleichen? - Was soll
list<Item> spiele = list<Item>();
tun? Warum nicht einfach den Teil rechts vom Gleich-Zeichen löschen? Also einfach nurlist<Item> spiele;
! (zu viel Java gemacht?) - Warum
list
stattvector
? (zu viel Java gemacht? ArrayList?)
- Was ist das
-
Danke erstmal für die Antwort.
Ja, ich komme aus Java aber das ist auch nun schon 5 Jahre her.Wenn ich new und delete streichen soll, wie zerstöre ich denn ein Objekt?
Und was ist der Mehrwert dies nicht zu benutzen. New erstellt und hält doch nur den Speicherplatz konstant be reicht, dachte ich?
Oder muss ich es dafür nur aus der Liste mit erase() nehmen?
Die Zeile 11 war ein Versuch ein bestimmtes Objekt zu löschen.
Die Grundidee war, dass der User sagt ich möchte Objekt mit ID XYZ löschen.Also gehe Ich meine Liste durch mit ner linearen suche , ziehe zu jedem die id raus und Vergleiche sie mit meiner vom User gegebenen.
Dass der rechte Teil der liste nicht notwendig ist, habe ich mir schon fast gedacht aber aus einem beispiel übernommen. Dachte ggf darf die liste nicht anders erstellt werden.
Aber code reduzieren etc würde bei mir am ende eh nochmal kommenEdit: achso und pointer.. Ja gut. Das habe ich vorher immer bei SVG Objekten benutzt und daher versucht damit mein Problem zu beheben.
-
@bobbgott sagte in Klassen - Objekte - Zeiger und Listen:
Oder muss ich es dafür nur aus der Liste mit erase() nehmen?
Ja, das reicht. Es ist ja kein Pointer!
Anders wäre es, wenn du eine
list<Item*>
(mit*
) hättest. Dann wären das ja alles Pointer und du müsstest das Objekt selber löschen. Aber: verwende wedernew
nochdelete
in C++ (sofern du nicht gerade eine Speicherverwaltungsklasse baust) (siehe auch)! Wenn du dynamischen Speicher brauchst, dann nimm Smart Pointer (erstellen mitstd::make_unique
oderstd::make_shared
). Kümmere dich nicht manuell um Speicherverwaltung. Du wirst es nämlich garantiert falsch machen. Nimm immer die dafür gedachten Container-Klassen.Und was ist der Mehrwert dies nicht zu benutzen. New erstellt und hält doch nur den Speicherplatz konstant be reicht, dachte ich?
New erstellt den Speicher UND ruft den Konstruktor des Objektes auf UND gibt dir danach einen Pointer in deinen Verantwortungsbereich und DU musst dich darum kümmern, den Speicher irgendwann (aber nur genau 1x) wieder freizugeben. Das ist SEHR SEHR fehleranfällig. Siehe den oben verlinkten Artikel der CPP Core Guidelines.
-
Danke - werde mir den Artikel mal durchlesen. Ist denke ich aktuell noch dem ganzen geschuldet, dass es eine Anfängeraufgabe ist und man manches nutzen soll um es zu verstehen, auch wenn es hier nicht das beste ist.
Da du aber bereits Zeile 11.. If( i->getId...) angesprochen hast. Ist dies denn falsch?
Also this-> id habe ich benutze, da ich oebn ein weiteres id für die Add habe.
Und *i da ich die Objekte ansprechen wollte und nicht den Listenspeicherplatz... Oder ist das dann auch falsch, wenn ich die Objekte ohne New erstelle und das Objekt direkt in der Liste SpeicherVielen dank im Voraus wie immer
EDIT :
Also i->getID() ist scheinbar falsch.... als ich i.getId() ausprobiert habe, hat aber auch der Compiler gemeckert und mit "->" vorgeschlagen.
Dennoch bekomme ich dort immer 0 raus. Falls jemand helfen kann