Übergeben freigegebener Zeiger als Argumente
Wenn ich das deklarieren eines Objekts, eingewickelt in ein shared pointer:
std::shared_ptr<myClass> myClassObject(new myClass());
dann wollte ich mich übergeben Sie Sie als argument an eine Methode:
DoSomething(myClassObject);
//the called method
void DoSomething(std::shared_ptr<myClass> arg1)
{
arg1->someField = 4;
}
Hat die oben erhöhen Sie einfach die shared_pt Verweiszähler und alles ist cool? Oder hinterlässt es ein dangling pointer?
Sind Sie immer noch, dies zu tun?:
DoSomething(myClassObject.Get());
void DoSomething(std::shared_ptr<myClass>* arg1)
{
(*arg1)->someField = 4;
}
Ich denke, dass der 2. Weg ist effizienter, da es nur 1 Kopie-Adresse (im Gegensatz zu den ganzen smart-pointer), aber der 1. Weg scheint mehr lesbar und ich weiß nicht antizipieren schieben Leistungsgrenzen. Ich will einfach nur, um sicherzustellen, dass es ist nicht etwas, was gefährlich ist.
Danke.
Kommentar zu dem Problem
const std::shared_ptr<myClass>& arg1
Die zweite Möglichkeit ist gebrochen, der erste ist idiomatisch, wenn Sie wirklich brauchen, Ihre Funktion zu Eigentum zu teilen. Aber,
DoSomething
wirklich brauchen, um Eigentum zu teilen? Es sieht aus wie es sollte nur einen Verweis anstelle... @SteveH : Es muss nicht, aber warum sollte die Funktion force special object ownership Semantik auf seine Anrufer, wenn Sie nicht tatsächlich benötigen? Ihrer Funktion tut nichts, was nicht besser wäre, als
void DoSomething(myClass& arg1)
. @SteveH : Der gesamte Zweck von smart pointers zu handhaben out of the ordinary-Objekt Eigentumsrecht-Probleme -- wenn Sie nicht über diese, Sie sollten nicht mithilfe der smart-Pointer in den ersten Platz. ;-] Als
shared_ptr<>
insbesondere muss als Wert übergeben, um tatsächlich das Eigentum zu teilen. Unrelated: in general,
, std::make_shared
ist nicht nur effizienter, sondern auch sicherer als die std::shared_ptr
Konstruktor. InformationsquelleAutor der Frage Steve H | 2012-05-31
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sicher, ich kann helfen Sie mit, dass. Ich nehme an, Sie haben ein Verständnis von Eigentum Semantik in C++. Ist das wahr?
Gut.
Ok, ich kann nur denken aus zwei Gründen zu nehmen
shared_ptr
argument:shared_ptr
s.Welches sind Sie interessiert?
Beispiele von solchen Funktionen umfassen
std::static_pointer_cast
benutzerdefinierte Komparator, oder Prädikate. Zum Beispiel, wenn Sie brauchen, um zu finden, die alle einzigartig shared_ptr von einem Vektor, die Sie benötigen, wie ein Prädikat.Genau.
Ja. Und wenn es ändert sich nicht der Mauszeiger, die Sie übergeben möchten, indem Sie const-Referenz. Es gibt keine Notwendigkeit zu kopieren, da Sie nicht brauchen, um Eigentum zu teilen. Das ist das andere Szenario.
Die eine, wo Sie teilen das Eigentum? Ok. Wie teilst du das Eigentum mit
shared_ptr
?Dann die Funktion, die benötigt wird, um eine Kopie einer
shared_ptr
, richtig?Nein, das ist eine pessimization. Wenn es als Verweis übergeben wird, die Funktion wird keine Wahl haben, sondern um das kopieren manuell. Wenn es wird durch Wert übergeben, wird der compiler bei der Auswahl der besten Wahl zwischen kopieren und verschieben, und führen Sie es automatisch. So, durch Wert übergeben.
Kann die Funktion verschieben Sie einfach die
shared_ptr
argument in seinem Speicher. Verschieben einesshared_ptr
ist Billig, weil es nicht ändern, dass jede Bezugnahme zählt.In diesem Fall
shared_ptr
ist völlig irrelevant für die Funktion. Wenn Sie möchten, um die Bearbeitung der pointee, nehmen Sie einen pointee, und lassen Sie den Anrufer Holen, was Eigentum Semantik, die Sie wollen.Die üblichen Regeln gelten. Smart pointers ändern Sie nichts.
Recht.
Ah, ein interessanter Grenzfall. Ich erwarte nicht, dass das oft passieren wird. Aber wenn es passiert, können Sie entweder als Wert übergeben, und ignorieren Sie die Kopie, wenn Sie brauchen es nicht, oder pass by reference und machen die Kopie, wenn Sie es brauchen.
Wenn Sie in einer situation, wo das wirklich wichtig ist, können Sie zwei überladungen, wobei ein const lvalue reference, andere nehmen eine rvalue-Referenz. Eine kopiert, der andere bewegt sich. Ein perfect-forwarding-Funktion template ist eine weitere option.
InformationsquelleAutor der Antwort R. Martinho Fernandes
Ich denke, die Menschen unnötig Angst mit raw-Pointern als Funktionsparameter. Wenn die Funktion nicht geht, speichern Sie den Mauszeiger oder sonst Auswirkungen auf die Lebensdauer, ein raw-pointer funktioniert genau so gut und stellt den kleinsten gemeinsamen Nenner. Betrachten Sie zum Beispiel, wie Sie bestehen würde, eine
unique_ptr
in eine Funktion, der eineshared_ptr
als parameter, der entweder per Wert oder per const-Referenz?Einen rohen Zeiger als Funktions-parameter nicht aus, dass Sie die Verwendung von smart-Pointer in der Aufruf-code, wo es wirklich wichtig ist.
InformationsquelleAutor der Antwort Mark Ransom
Ja, die ganze Idee über einen shared_ptr<> ist, dass mehrere Instanzen enthalten die gleichen raw-pointer und der zugrunde liegende Speicher wird nur freigegeben werden, wenn die Letzte Instanz von shared_ptr<> ist zerstört.
Ich würde vermeiden, dass ein Zeiger auf ein shared_ptr<> so, dass Niederlagen der Zweck, wie Sie jetzt im Zusammenhang mit raw_pointers wieder.
InformationsquelleAutor der Antwort R Samuel Klatchko
Passing-by-Wert in Ihrem ersten Beispiel ist sicher, aber es ist ein besseres idiom. Pass von const-Referenz, wenn möglich - ich würde sagen ja, auch wenn der Umgang mit smart Pointern. Dein zweites Beispiel ist nicht gerade gebrochen, aber es ist sehr
!???
. Dumm, nicht, etwas zu erreichen und Niederlagen Teil des point-of-smart-Pointer, und gehen Sie in einen buggy Welt der Schmerzen, wenn Sie versuchen, Sie zu dereferenzieren und ändern Dinge.InformationsquelleAutor der Antwort djechlin