Vorbei an smart-Pointer by reference
Smart-Pointer sind in der Regel winzig, so dass als Wert übergeben werden, ist das kein problem, aber gibt es irgendwelche Probleme die übergabe von Referenzen auf Sie; oder vielmehr sind es bestimmte Fälle wo dies darf nicht getan werden?
Schreibe ich eine wrapper-Bibliothek und einige meiner Klassen wrap smart-pointer-Objekte in der zugrunde liegenden Bibliothek... meine Klassen sind nicht smart-Pointer, aber die APIs, die derzeit passieren smart-pointer-Objekte von Wert.
e.g aktuelle code:
void class::method(const AnimalPtr pAnimal) { ... }
wird
void class::method(const MyAnimal &animal){...}
wo MyAnimal
ist meine neue wrapper-Klasse gekapselt AnimalPtr
.
Gibt es keine Garantie die Wrapper-Klassen nicht an einem Tag wachsen über die Verpackung einer smart-pointer, also als Wert übergeben werden, macht mich nervös.
- Im Allgemeinen speichern Verweise auf smart pointers ist nicht eine gute Idee, aber die übergabe einer Referenz, wenn Sie wissen, dass es nicht gespeichert werden ist in der Regel ok, siehe zum Beispiel diese Frage: stackoverflow.com/questions/179105/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Du sollte pass shared Pointer per Referenz, nicht Wert, in den meisten Fällen. Während die Größe eines
std::shared_ptr
ist klein, die Kosten für das kopieren beinhaltet eine Atomare operation (konzeptionell eine Atomare Inkrement-und eine Atom-Dekrement auf die Vernichtung der Kopie, obwohl ich glaube, dass einige Implementierungen gelingt, eine nicht-Atomare Inkrement).In anderen Fällen, zum Beispiel
std::unique_ptr
Sie vielleicht lieber durch Wert übergeben, als die kopieren haben sich zu bewegen und klar Dokumente, dass das Eigentum an dem Objekt übertragen wird, um die Funktion (wenn Sie nicht wollen, zu übereignen, übergeben Sie eine Referenz auf das Reale Objekt, nicht diestd::unique_ptr
).In anderen Fällen kann Ihre Laufleistung variieren. Sie müssen sich bewusst sein, was die Semantik von Kopie für Ihre smart-pointer, und ob Sie müssen zu bezahlen, für die Kosten oder nicht.
std::unique_ptr<T> const&
- es impliziert, dass dies ist ein Objekt, dessen Besitzer, und Nein, Sie können es nicht haben. Ebensostd::unique_ptr<T>&
bedeutet "dies ist ein Objekt, dessen Besitzer, aber Sie können ändern, die Eigenverantwortung, wenn Sie wollen". Auf der anderen Seite, ich mag auch "pass-through -unique_ptr
", wo Sie dieunique_ptr
Wert und senden Sie es per Wert in der return-Wert...std::unique_ptr
unnötig, vorbeiT&
eindeutig impliziert, dass es ein owned (von jemandem, irgendwo) - Objekt und ist flexibler (neben der Ermöglichung einer Ebene von const-correctness, dass Sie nicht mit derconst&
zu den smart-pointer. Vorbeistd::unique_ptr<T>&
ist unklar, auf den Anrufer, als ob das Objekt immer noch meins oder deins, hast du Anspruch auf das Eigentum? oder kann ich die Zeiger nach dem aufrufen?Es ist ok, um einen intelligenten Zeiger per Referenz, außer wenn es sich um einen Konstruktor. In einem Konstruktor es ist möglich, speichern Sie eine Referenz auf das original-Objekt, das verstößt gegen den Vertrag des smart-Pointer. Sie würde wahrscheinlich bekommen Speicherbeschädigung wenn du das getan hast. Auch wenn Ihr Konstruktor nicht heute Shop die Referenz ist, würde ich noch vorsichtig sein, da änderungen am code und es ist eine einfache Sache zu verpassen, wenn Sie sich später entscheiden, die Sie benötigen, um den Variablen mehr.
In eine normale Funktion, Sie können nicht speichern Sie eine Funktion parameter als Referenz überall da Verweise müssen gesetzt werden, die während Ihrer Initialisierung. Könnten Sie weisen der Bezugnahme auf einige mehr-Leben, non-Referenz-variable, aber das wäre eine Kopie, und so erhöhen Sie seine Lebensdauer entsprechend. Also in jedem Fall, dass Sie nicht halten konnte auf die Vergangenheit, wenn die aufrufende Funktion haben könnte, befreit es. In diesem Fall bekommen Sie vielleicht einen kleinen performance-boost mit einem Verweis, aber ich würde nicht planen es zu merken-in den meisten Fällen.
Also ich würde sagen - Konstruktor, immer durch Wert übergeben; andere Funktionen, übergabe per Referenz, wenn Sie wollen.
Foo* f = smart_foo.get()
, und Sie können nicht garantieren, dass die Lebensdauer vonf
.