Rückgabetyp einer Funktion als Smartpointer
Rückgabetyp einer Funktion als Smartpointer
Guten Morgen,
ich habe folgendes gegeben:
- einen std::vector als Member einer Klasse
- eine Funktion die diesen Container als smart-pointer, also nicht als Kopie, zurückgeben soll.
Es gibt ja diesen std::shared_ptr.
Kann ich nicht meinen Container in der Funktion irgendwie als diesen smart-pointer zurückgeben?
Ich meine, ich könnte ja meinen Container von Anfang an als shared_ptr deklarieren, nur irgendwie passt mir das nicht recht...
Der Eigentümer bleibt definitiv von Anfang bis Ende eben diese Klasse, ich möchte nur an einer Stelle auf diesen Container von Außen zugreifen...
Ich hoffe ihr versteht mein Problem.
Gruß
ich habe folgendes gegeben:
- einen std::vector als Member einer Klasse
- eine Funktion die diesen Container als smart-pointer, also nicht als Kopie, zurückgeben soll.
Es gibt ja diesen std::shared_ptr.
Kann ich nicht meinen Container in der Funktion irgendwie als diesen smart-pointer zurückgeben?
Ich meine, ich könnte ja meinen Container von Anfang an als shared_ptr deklarieren, nur irgendwie passt mir das nicht recht...
Der Eigentümer bleibt definitiv von Anfang bis Ende eben diese Klasse, ich möchte nur an einer Stelle auf diesen Container von Außen zugreifen...
Ich hoffe ihr versteht mein Problem.
Gruß
- kimmi
- Moderator
- Beiträge: 1405
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Rückgabetyp einer Funktion als Smartpointer
Du meinst so etwas wie:
Problem dabei: der shared_ptr wird die Anzahl der Referenzen für dich verwalten ausgenommen der Ownership, die deine entprechende Klasse innehält. Wenn dieser nun auf 0 geht, wird versucht, dein Container abzuräumen, ohne dass der Owner davon erfährt. Versuch doch mal std::weak_ptr: http://en.cppreference.com/w/cpp/memory/weak_ptr
Gruß Kimmi
Code: Alles auswählen
make_shared<dein_container>
Gruß Kimmi
Re: Rückgabetyp einer Funktion als Smartpointer
Wunderbar, das seht gut aus!
Ich danke schon mal...
Ich danke schon mal...
Re: Rückgabetyp einer Funktion als Smartpointer
Mh... so richtig gefällt mir das auch nicht.
Ich musste da trotzdem meinen Container als shared_ptr deklarieren.
Ich mache das mal mit etwas Code deutlich:
Jetzt könnte ich das aber auch so machen damit das mit dem weak_ptr funktioniert
Nur irgendwie habe ich dabei das Gefühl, dass das "schlechtes" Design ist, da ja eben die Klasse eigentümer bleibt.
Kann sein das mein Gefühl sich da irrt und das das eben der gängige Weg ist, so wie der 2te Code-Ausschnitt!
[edit]
Ich meine, wenn ich diesen Container niemals hinausgebe, sondern maximal nur über die einzelnen Eleme von außen iterieren möchte, dann ist es doch quatsch ihn als shared_ptr zu deklarieren, oder?
Wenn, dann würde ich sagen, das ein unique_ptr da nur als smart-pointer sinn macht...
Die Frage ist eben, wie ist denn nun der "State of the Art" dabei?
Ich musste da trotzdem meinen Container als shared_ptr deklarieren.
Ich mache das mal mit etwas Code deutlich:
Code: Alles auswählen
Class A
{
private:
std::vector<Foo> mContainer;
public:
// hier will ich nur einen smart-pointer auf den Container zurückgeben
aSmartPtr<std::vector<Foo>> getMyContainer();
}
Code: Alles auswählen
Class A
{
private:
std::shared_ptr<std::vector<Foo>> mContainer;
public:
// hier will ich nur einen smart-pointer auf den Container zurückgeben
std::weak_ptr<std::vector<Foo>> getMyContainer();
}
Kann sein das mein Gefühl sich da irrt und das das eben der gängige Weg ist, so wie der 2te Code-Ausschnitt!
[edit]
Ich meine, wenn ich diesen Container niemals hinausgebe, sondern maximal nur über die einzelnen Eleme von außen iterieren möchte, dann ist es doch quatsch ihn als shared_ptr zu deklarieren, oder?
Wenn, dann würde ich sagen, das ein unique_ptr da nur als smart-pointer sinn macht...
Die Frage ist eben, wie ist denn nun der "State of the Art" dabei?
- kimmi
- Moderator
- Beiträge: 1405
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Rückgabetyp einer Funktion als Smartpointer
Warum willst du denn den Container herausreichen? Wenn du über den COntainer iterieren möchtest, biete in Class A doch einfach ein Interface dafür an.
Kimmi
Kimmi
Re: Rückgabetyp einer Funktion als Smartpointer
Und wie würde so ein Interface dazu aussehen?
- dot
- Establishment
- Beiträge: 1745
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: Rückgabetyp einer Funktion als Smartpointer
Wenn du nicht den Besitz nach außen abgeben willst, dann sind Smartpointer rein prinzipiell fehl am Platz, denn der einzige Sinn von Smartpointern ist die Repräsentation von Besitzverhältnissen. Was genau willst du denn erreichen; wieso muss der Container von außen erreichbar sein?
- Sternmull
- Establishment
- Beiträge: 264
- Registriert: 27.04.2007, 00:30
- Echter Name: Til
- Wohnort: Dresden
Re: Rückgabetyp einer Funktion als Smartpointer
Für mich klingt es so als würde es auch schlichtweg eine Referenz tun. Wenn deine Klasse die Lebenszeit des Containers definieren soll, und der Nutzer der Klasse über diesen Fakt informiert ist und das auch sinnvoll so ist, dann gibt es hier keinen Bedarf für die referenzgezählte Lebenszeitverwaltung für die man Smartpointer verwendet. Wenn der Nutzer den Container nur angucken, aber nicht modifizieren soll, dann nimm eine konstante Referenz.
shared_ptr und andere Smartpointer sind nur dann sinnvoll wenn ein Objekt so lange erhalten bleiben soll bis der letzte Nutzer (also der letzte Besitzer eines shared_ptr der darauf zeigt) es nicht mehr referenziert, und nicht klar ist wer der Letzte ist. Das passiert z.B. wenn es um eine Ressource geht die von vielen Objekten geteilt wird die in beliebiger Reihenfolge (z.B. aufgrund von Nutzereingaben) zerstört werden. Also z.B. zerstörbare Einheiten in einem Spiel die alle die gleiche Textur brauchen.
shared_ptr und andere Smartpointer sind nur dann sinnvoll wenn ein Objekt so lange erhalten bleiben soll bis der letzte Nutzer (also der letzte Besitzer eines shared_ptr der darauf zeigt) es nicht mehr referenziert, und nicht klar ist wer der Letzte ist. Das passiert z.B. wenn es um eine Ressource geht die von vielen Objekten geteilt wird die in beliebiger Reihenfolge (z.B. aufgrund von Nutzereingaben) zerstört werden. Also z.B. zerstörbare Einheiten in einem Spiel die alle die gleiche Textur brauchen.
- kimmi
- Moderator
- Beiträge: 1405
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Rückgabetyp einer Funktion als Smartpointer
So etwas in Kurzform. KAnnst nat. gern Referenzen herausgeben:
Kimmi
Code: Alles auswählen
class A {
std::vector<myStruct*> m_data;
public:
myStruct *getAt( size_t i ) const;
};
Re: Rückgabetyp einer Funktion als Smartpointer
Okay. Soweit danke erstmal.
Das ich nicht zwingend smartpointer verwenden muss scheint mir nun auch eher sinnvoll.
Ich will mich eben mit modern c++ vertraut machen und versuch da so oft wie möglich die neuen features zu verweneen. Aber anscheinend ist das nicht immer angebracht...
Zum Hintergrund meiner Frage:
Mein Spiel hat eine klasse Spiel. Diese verwaltet UI, Resourcen und sonst noch etwas.
Dann gibt es eine Level-klasse deren eigentümer die Klasse spiel ist.
Diese Level-klasse kapselt alle spielobjekte.
Dann gibt es noch eine klasse die das zeichnen übernimmt. Deren eigentümer ist ebenfalls die Spiel-klasse.
Nun wollte ich das gerne so haben:
Naja, und da hätte ich von ausen alle zeichenbaren objekte von Level abfragen müssen.
Das heißt, ich werds so tun....
Das ich nicht zwingend smartpointer verwenden muss scheint mir nun auch eher sinnvoll.
Ich will mich eben mit modern c++ vertraut machen und versuch da so oft wie möglich die neuen features zu verweneen. Aber anscheinend ist das nicht immer angebracht...
Zum Hintergrund meiner Frage:
Mein Spiel hat eine klasse Spiel. Diese verwaltet UI, Resourcen und sonst noch etwas.
Dann gibt es eine Level-klasse deren eigentümer die Klasse spiel ist.
Diese Level-klasse kapselt alle spielobjekte.
Dann gibt es noch eine klasse die das zeichnen übernimmt. Deren eigentümer ist ebenfalls die Spiel-klasse.
Nun wollte ich das gerne so haben:
Code: Alles auswählen
Spiel::run()
{
renderer.renderLevel(level)
}
Das heißt, ich werds so tun....
- dot
- Establishment
- Beiträge: 1745
- Registriert: 06.03.2004, 18:10
- Echter Name: Michael Kenzel
- Kontaktdaten:
Re: Rückgabetyp einer Funktion als Smartpointer
Ich würde wohl dem Level eine draw(renderer) Methode geben, die dann einfach selbst die entsprechenden infos an renderer.drawLevel(stuff) oder was auch immer weiterreicht. Auf diese Weise muss überhaupt nie etwas von außen abgefragt werden.
Btw: Um einen std::vector zu returnen, brauchst du keine Smartpointer. Einfach by value returnen. In C++11 wird dann eh gemoved (wenn nötig kannst du explizit moven, sollte man aber nur machen, wo es nötig ist) und ansonsten wird bei jedem guten Compiler sowieso die Copy-Elision greifen... ;)
Btw: Um einen std::vector zu returnen, brauchst du keine Smartpointer. Einfach by value returnen. In C++11 wird dann eh gemoved (wenn nötig kannst du explizit moven, sollte man aber nur machen, wo es nötig ist) und ansonsten wird bei jedem guten Compiler sowieso die Copy-Elision greifen... ;)
Re: Rückgabetyp einer Funktion als Smartpointer
Ja, das war jetzt zum schluss auch mein gedanke. Werd ich wohl so tun.dot hat geschrieben:Ich würde wohl dem Level eine draw(renderer) Methode geben, die dann einfach selbst die entsprechenden infos an renderer.drawLevel(stuff) oder was auch immer weiterreicht. Auf diese Weise muss überhaupt nie etwas von außen abgefragt werden.