Liste von Objekten
-
Naja ich meinte dynamisch mit new erzeugt Objekte.
void addSchueler(int id) { m_schueler.push_back(new Schueler(id)); }
Wie sollte man das mit einer Kopie realisieren?
-
Leon222 schrieb:
Naja ich meinte dynamisch mit new erzeugt Objekte.
void addSchueler(int id) { m_schueler.push_back(new Schueler(id)); }
Wie sollte man das mit einer Kopie realisieren?
Ich verstehe nicht, was Du meinst, verstehe Dein Problem nicht. Ich weiß nicht, was Du wissen willst.
-
SeppJ schrieb:
Im übrigen: Du brauchst keine Zeiger. Hast du früher zufällig mal Java programmiert? In C++ macht man das was du da zeigst eigentlich mit Kopien. Die dynamische Verwaltung ist genau das, wozu die Container gut sind. Du musst gar nicht mehr selbst mit new/delete arbeiten.
Das meinte ich. Ich will eben zur Laufzeit Objekte anlegen. Eben z.B. mit einer methode neuerSchueler. Aber wie bitte soll das ohne new mit Kopien gehen?
-
Leon222 schrieb:
Ich will eben zur Laufzeit Objekte anlegen. Eben z.B. mit einer methode neuerSchueler. Aber wie bitte soll das ohne new mit Kopien gehen?
Du siehst wohl den Wald vor lauter Bäumen nicht. Guck Dir nochmal ganz genau mein letztes Codebeispiel an.
-
Leon222 schrieb:
Ich will eben zur Laufzeit Objekte anlegen. Eben z.B. mit einer methode neuerSchueler. Aber wie bitte soll das ohne new mit Kopien gehen?
Du siehst wohl den Wald vor lauter Bäumen nicht. Guck Dir nochmal ganz genau mein letztes Codebeispiel an.
-
Nein so richtig sehe ich das noch nciht. heißt das ich kann einfach schreiben:
void addSchueler(int id) { m_schueler.push_back(Schueler(id)); }
-
Leon222 schrieb:
Nein so richtig sehe ich das noch nciht. heißt das ich kann einfach schreiben:
void addSchueler(int id) { m_schueler.push_back(Schueler(id)); }
Genau! Dann muss m_schueler aber als
std::list<Schueler>
deklariert sein, bei der Zeigervariante mit new wäre es jastd::list<Schueler*>
.
-
Gut das war mir bisher nciht bekannt, dass das ohne new geht. Hat es denn einen Vorteil, dass ganze ohne Zeiger zu realisieren? Und ist nun List oder Vektor besser für mein Vorhaben. Was ich jetzt so gelesen habe würde ich List den Vorzug geben.
-
Leon222 schrieb:
Gut das war mir bisher nciht bekannt, dass das ohne new geht. Hat es denn einen Vorteil, dass ganze ohne Zeiger zu realisieren?
Der Vorteil besteht darin, dass du keine manuelle Speicherverwaltung mehr hast.
Leon222 schrieb:
Und ist nun List oder Vektor besser für mein Vorhaben. Was ich jetzt so gelesen habe würde ich List den Vorzug geben.
Dazu wurde dir schon zwei Mal eine Antwort gegeben (SeppJ und drakon).
-
Naja mir wurden halt mehrmals die Vor und Nachteile der beiden Klassen genannt. Ich wollte nur nochmal wissen, ob ich das jetzt richtig interpretiert habe, und List für mich das beste ist.
-
Wie erwähnt ist das schwer zu sagen, ohne genau zu wissen, welche Operationen wie häufig vorkommen und ob besondere Anforderungen (z.B. Gültigkeit der Iteratoren) gestellt werden. Nimm fürs Erste einmal
std::vector
, für die meisten Fälle ist er am geeignetsten.
-
Also ich wollte erst einmal ein kleines Testprojekt machen wo ich wie schon geschrieben Objekte in die Liste einfüge, und anhand der id wieder lösche. Ansonsten werden die Objekte nur für eine Methode gebraucht und dort soll eine Variable aller Objekte aufsummiert werden. Also z.B. den Durchschnitt aller Gesamtnoten der Schüler berechnen. Da sollte bald die Liste besser sein.
Worüber ich mir jetzt noch Gedanken mache ist die Nummerierung der Objekte. Ich wollte das ja erst mit new machen. Da hätte ich die Nummerierung der Klasse Schüler überlassen. Dort 2 static Variablen letzte id und anzahl. und eine normale Variable id. Beim Erzeugen eines neuen Objektes wird id der wert ++letzteid zugewiesen. Aber das klappt ja jetzt durch das kopieren nicht mehr, oder?
-
Kannst du als Nummer nicht den Index des Containers (in dem Fall
std::vector
) verwenden? Oder wofür brauchst du die Nummerierung genau?
-
Also die Nummerierung des Vektor ist vlt zwecks löschen nciht so gut, oder? Also die Nummerierung benötige ich um das Objekt zu löschen. Also z.B. Schüler mit Nummer 14546 löschen.
-
Entweder du gibst der Schüler-Klasse diese Eigenschaft und führst im Container eine lineare Suche durch, oder du bildest Schlüssel-Wert-Paare mit Nummern als Schlüsseln und Schülern als Werten. Dazu kannst du
std::map
verwenden.
-
Klingt mir danach, dass du eine
std::map
benötigst.Oder falls du Boost bereits verwendest und die ID nicht doppelt speichern willst (also als Key und im Objekt selber), dann gäbe es Boost.MultiIndex:
class pupil { private: int id_; // usw. public: int get_id() const { return id_; } // usw. }; // ... typedef boost::multi_index::multi_index_container < pupil, boost::multi_index::indexed_by < boost::multi_index::const_mem_fun<pupil, int, &pupil::get_id> > > pupil_set; // ...
multi_index_container
braucht aber etwas Zeit, bis man das Ding schlucken kannGrüssli
-
Also Map wäre ich mir anschauen, oder halt dem Schüler die Eigenschaft id geben. Dann muss sich aber das Hauptprogramm darum kümmern, dass es keine Doppelten Nummern gibt, oder?
Wie kann ich denn eigentlich verhindern, dass Im Hauptprogramm ein Schüler erstellt wird. Denn das soll nur über die Klasse Schule möglich sein. Reicht es da den Konstruktor private zu machen?
-
Hallo nochmal,
was bringt den map für einen Vorteil gegenüber der dem, dass ich der Klasse Schüler eine Eigenschaft ID gebe? Die Verwaltung muss ja eh über das Hauptprogramm geschehen, oder?
-
Eine Map ist eine Assoziation zwischen Nummer und Schüler. Die Nummer ist dabei nicht direkt die Eigenschaft eines Schülers (dieser kann auch ohne Nummer auskommen). Vorteil und gleichzeitig Nachteil ist eine logarithmische Zugriffszeit (im Gegensatz zu konstantem Einfügen, Random Access und linearem Löschen bei sequentiellen Containern).
Wenn du hingegen die Nummer als Schüler-Attribut fest verankern willst, benutze eine Membervariable in der Schüler-Klasse.
-
Nexus schrieb:
...Wenn du hingegen die Nummer als Schüler-Attribut fest verankern willst, benutze eine Membervariable in der Schüler-Klasse.
... und dann kann man schön std::set mit entsprechender Vergleichsfunktion (vergleich nur das jeweilige Attribut) nehmen. Das spart eine Menge Organisation (Ordnung, Einmaligkeit sicherstellen, ...), die man sonst für std::vektor (der zwischen seinen Elementen gar keinen Zusammenhang kennt) von Hand programmieren muss.
Wenn es Dir (Leon) im Wesentlichen darum geht, "Containerverwaltung" (Einfügen Löschen, Kopieren, Suchen, ...) kennenzulernen, solltest Du Dir neben den diversen Containern (hier unter "Containers library") ganz dringend auch die ganzen Algorithmen ansehen (->
#include <algorithm>
; hier ein Übersicht).
Danach noch die Iteratoren und dann merkt man, dass es einfach nicht stimmt, dass man mit C++ "alles selbst machen muss".Gruß,
Simon2.