shared_ptr für Argumente Sinnvoll?
-
Hallo,
kann man in C++ ohne Performance Verlust statt Referenzen und Zeigern einfach immer shared_ptr nehmen?
Ich denke ihr fragt euch warum, es hat den Sinn, da öfters mal ein Argument an ein Objekt weiter gegeben wird(Das Objekt speichert z.B. dann dieses Argument um es später zu verwenden), dass kurz danach aber ungültig wird und so im Speicher gelöscht wird, jetzt kann das Objekt ja nicht mehr auf die Variable zugreifen.
Was mir dagegen einfällt, um das kopieren von Argumenten zu unterbinden war entweder einfach den Speicher manuell zu verwalten(new und delete), was jedoch ziemlich Fehleranfällig wäre, oder einfach das Java Prinzip zu imitieren, indem man mit shared_ptr arbeitet.
Ich kenne mich mir shared_ptr nicht so aus und weiß deshalb auch nicht, ob man das so machen sollte.
Ich hoffe ich denke nicht all zu falsch und ihr könnt mir etwas helfen.
-
Versuche shared_ptr Nutzung zu vermeiden.
Wenn du ein Objekt auf dem Heap hast, halte es via unique_ptr in einer geeigneten Funktion/Klasse.
Braucht eine andere Funktion dieses Objekt, übergib es als Referenz.
Braucht eine andere Klasse dieses Objekt speichere in der Klasse einen Pointer darauf.
Nur - und nur dann - wenn die andere Klasse dieses Objekt auch besitzt - sprich, wenn diese das Objekt weiterreferenzieren soll, auch wenn der alte Besitzer nicht mehr exisitiert, verwende shared_ptr.
-
Das heißt, ich kann unqiue_ptr benutzten, ohne einen Performance Verlust zu erleiden?
-
BuschmannMichael schrieb:
Das heißt, ich kann unqiue_ptr benutzten, ohne einen Performance Verlust zu erleiden?
Ja.
unique_ptr bietet keinen Overhead.
-
kann man in C++ ohne Performance Verlust statt Referenzen und Zeigern einfach immer shared_ptr nehmen?
Das sind drei verschiedene Dinge. Werfe sie nicht in einen Topf. Und
shared_ptrist, wie Nathan schon erklärt hat, für shared ownership da. Standardmäßig verwendet manunique_ptr, und auch nur, wenn man tatsächlich einen besitzenden Smart-Pointer braucht.
-
Mh, mein Problem ist, das ich nie weiß, wenn ich Funktionen habe der ich Argumente gebe, wie ich eine Kopie des Parameters vermeiden kann, besonders wenn es in einem Programm auf Geschwindigkeit ankommt.
In Java war das ja nie ein Problem, da das ja im Prinzip wie der shared_ptr war, jede Variable(Außer Primitive Typen) waren Referenzen und wurden gelöscht sobald die Variable nicht mehr gebraucht bzw.Referenziert wurde, in C++ sobald der Gültigkeitsbereich abläuft, aber wie ihr schon sagt, kann/sollte ich nicht jede Variable als shared_ptr deklarieren.
Nur weiß ich jetzt nicht wie ich diesen Bereich in C++ behandeln soll.
Ich hoffe jemand kann mir weiterhelfen.
-
Einfach per Referenz übergeben:
void f(const grosse_klasse& parameter) ...Ist sogar besser wie in Java, da garantiert wird, dass der Parameter nicht verändert werden kann.
-
wie ich eine Kopie des Parameters vermeiden kann
Indem du nicht das Objekt selbst, sondern einen Verweis darauf an die Funktion gibst. Dafür gibt es drei Möglichkeiten: Zeiger, Referenzen, oder einen Wrapper um eines von Beiden.
-
Arcoth schrieb:
Dafür gibt es drei Möglichkeiten: Zeiger, Referenzen, oder einen Wrapper um eines von Beiden.
Wrapper um Referenzen lieber nicht.
-
liebernicht schrieb:
Arcoth schrieb:
Dafür gibt es drei Möglichkeiten: Zeiger, Referenzen, oder einen Wrapper um eines von Beiden.
Wrapper um Referenzen lieber nicht.
Also ich finde
reference_wrapperschon sinnvoll. (nicht als Funktionsparameter, i.A.)
-
Arcoth schrieb:
liebernicht schrieb:
Arcoth schrieb:
Dafür gibt es drei Möglichkeiten: Zeiger, Referenzen, oder einen Wrapper um eines von Beiden.
Wrapper um Referenzen lieber nicht.
Also ich finde
reference_wrapperschon sinnvoll. (nicht als Funktionsparameter, i.A.)reference_wrapper ist aber ein misnomer. Es ist unmöglich, reference_wrapper mit einer Referenz zu implementieren. (In Wirklichkeit ist es ein pointer_wrapper)
-
Ein pointer_wrapper könnte aber den null-Pointer enthalten. Der reference_wrapper bringt dieselben Garantien mit sich, die eben auch eine Referenz bringt. Naja, vielleicht gibt es irgendwelchen abstrusen Fälle, wo das kopieren der Referenz die Lebenszeit verlängern würde, aber der reference_wrapper sich anders verhält oder andersherum oder wie auch immmer... aber ansonsten...
-
Es ist unmöglich, reference_wrapper mit einer Referenz zu implementieren.
Implementationsdetails sind für die Semantik irrelevant.
-
Arcoth schrieb:
Es ist unmöglich, reference_wrapper mit einer Referenz zu implementieren.
Implementationsdetails sind für die Semantik irrelevant.
Dann sind wir uns ja einig, dass es nicht sinnvoll ist, eine Referenz zu wrappen.
-
Der Sinn und Zweck von reference_wrapper ist es ja eigentlich doch auch nicht direkt eine Referenz zu wrappen, sondern Information bezüglich der Behandlungsweise an Funktionstemplates weiterzureichen, oder etwa nicht? Also Qualifizierer reinzu"pushen", anstatt implizit und nicht steuerbar "ziehen" zu lassen. Oder habe ich da etwas falsch verstanden?
-
Ja zunächst mal würde ich ja auch Referenzen für Argumente nehmen,
aber oft läuft dann später der Namensraum des Prameters ab, sodass ich später nicht mehr mit dem Übergebenen Parameter arbeiten kann.
Meine Idee war eigentlich als Parameter dann einfach einen unique_ptr zu nehmen, sodass ich den Gültigkeitsbereich verschieben kann.Und noch eine Frage, wenn ich eine Constante Referenz übergebe, ist doch nur sozusagen die Speicheradresse constant, sodass man immer noch sämtliche Funktionen der Parameters ausführen kann(Also mann kann der Referenz keinen neuen Referendar zuweisen)?
-
BuschmannMichael schrieb:
aber oft läuft dann später der Namensraum des Prameters ab, sodass ich später nicht mehr mit dem übergebenen Parameter arbeiten kann.
Wat
Du meinst wohl, die Variable muss nach Ende des Scopes erhalten bleiben. Dann musst du einen smart-pointer erzeugen, am besten unique_ptr.
-
BuschmannMichael schrieb:
Und noch eine Frage, wenn ich eine Constante Referenz übergebe, ist doch nur sozusagen die Speicheradresse constant, sodass man immer noch sämtliche Funktionen der Parameters ausführen kann(Also mann kann der Referenz keinen neuen Referendar zuweisen)?
Es macht keinen Sinn, von konstanten Referenzen zu sprechen (per Definition sind Referenzen unveränderlich). Einmal gebunden, kann der Verweis nicht mehr verändert werden.
Du meinst Const-Referenzen, oder ausführlicher "Referenzen auf const-Objekte". Das
constbedeutet, dass du das referenzierte Objekt durch diese Referenz nicht ändern kannst. Die Referenz selbst kannst du sowieso nie ändern.