Liste als Klassen-Attribut - Pointer geeignet?
-
Servus,
es gibt im Buch von Breymann (Der C++-Programmierer)ja eine feine Fragenkette, bei der am Ende die Antwort klar ist, in welcher Form Methoden- bzw. Funktionsparameter gesetzt werden sollten.
Ich suche so etwas für die Attribute meiner Klasse. Wann nehme ich hier const, wann nehme ich vor allem Pointer als Klassenattribute, wie stelle ich dann dabei sicher, dass mir der Pointer auch immer besetzt ist?
Um einmal konkret zu werden: ich habe eine Klasse 'Tisch'. Jetzt hat der Tisch einen vektor<bein> und da ich vielleicht auch Tische mit hunderttausenden von Beinen haben werde, will ich als Attribut gerne einen Pointer zur Liste speichern statt direkt die Liste - wie mache ich das?
Damit mir der Pointer nicht abhaut, habe ich diesen Vektor mit den bein-Instanzen in einem Namespace 'global' angelegt und in die main.cpp geschrieben - somit hoffe ich, dass der Pointer im gesamten Programmablauf besetzt sein wird - lieg ich da richtig?
Danke vorab.
-
wann nehme ich vor allem Pointer als Klassenattribute, wie stelle ich dann dabei sicher, dass mir der Pointer auch immer besetzt ist?
Pointer sind besonders in zwei Fällen nötig:
1. Daten können aus irgendeinem Grund nicht auf dem Stack angelegt werden (z.B. ist ein Array von 100000 ints zu groß für den Stack), sind aber fester Bestandteil des Objekts. In diesem Fall setzt man dann RAII ein, d.h. man fordert innerhalb des Konstruktors den Speicherplatz an und setzt den Pointer, im Destruktor gibt man die Daten wieder frei.2. Das Objekt kann auch unabhängig vom Pointee funktionieren, zwischen Pointee und Zeiger besteht also nur eine lose Verbindung. Vor allem kann der Zeiger auch 0 sein (also nicht gesetzt).
Es gibt natürlich noch andere Fälle, in denen Zeiger als Membervariablen angemessen sind - man muss sich halt immer von Fall zu Fall Gedanken machen.
Jetzt hat der Tisch einen vektor<bein> und da ich vielleicht auch Tische mit hunderttausenden von Beinen haben werde, will ich als Attribut gerne einen Pointer zur Liste speichern statt direkt die Liste
Brauchst du nicht. std::vector verwaltet seine Elemente im Heap (!= Stack), d.h. es ist absolut problemlos möglich auch einen Vektor mit 1000 Elementen als Membervariable zu haben.
wie mache ich das?
Wenn du wirklich einen Pointer zu einer std::list<bein> haben möchtest, dann hast du halt einen Member
std::list<bein>* m_beine.Damit mir der Pointer nicht abhaut, habe ich diesen Vektor mit den bein-Instanzen in einem Namespace 'global' angelegt und in die main.cpp geschrieben - somit hoffe ich, dass der Pointer im gesamten Programmablauf besetzt sein wird - lieg ich da richtig?
Versuche globale Variablen zu vermeiden. Wie oben geschrieben kann der Vektor auch ruhig Attribut der Klasse sein.
-
Jay1980 schrieb:
Um einmal konkret zu werden: ich habe eine Klasse 'Tisch'. Jetzt hat der Tisch einen vektor<bein> und da ich vielleicht auch Tische mit hunderttausenden von Beinen haben werde, will ich als Attribut gerne einen Pointer zur Liste speichern statt direkt die Liste
Diese Argumentation verstehe ich nicht. Es klingt so, als würdest Du glauben, dass ein Objekt des folgenden Typs...
class Tisch { vector<Bein> beine; ... };...nicht mehrere Beine besitzen könnte.
Jay1980 schrieb:
[...] lieg ich da richtig?
Hä?

Zusatz:
Dein Thread-Titel ist "List als Klasse-Attribut, pointer geeignet?". Es ist mir nicht ganz klar, wie der erste Teil der Frage mit dem zweiten Teil zusammen hängt. Wenn Du einen Zeiger als Klassenattribut verwendest, ist das ein Zeiger und kein Vector oder keine Liste. Es gibt im Prinzip drei Kombinationen, wie man Objektbeziehungen modellieren und implementieren kann.1. ein X ist ein Teil von einem Y (logisch und auch implementierungs-technisch):
class Y { X teil; };2. ein Y kennt ein X. Implementierung über Zeiger
class Y { X* bekannter; };3. ein X ist logisch gesehen ein Teil von einem Y. Eine Implementierung per Zeiger erfordert das Abschalten oder Überschreiben der Default-Kopiersemantik, da ein Zeiger mit der Default-Kopiersemantik nur eine "kennt-ein"-Beziehung modelliert:
class Y { X* logischer_teil; public: Y() : logischer_teil(new X) {} Y(Y const&); Y& operator=(Y const&); ~Y(); };Wenn Du jetzt nur Weg 3 wählen willst, weil ein Y dynamisch viele Xs haben können soll, dann kannst Du entweder Weg 1 mit einem vector<bein> wählen oder Du programmierst Dir einen vektor innerhalb von Y mit Weg 3 nach (würde ich von abraten). Also, falls Du um um Fall 3 rumkommst, tue es.
kk