shared_ptr per Wert oder Referenz



  • DKlay schrieb:

    OK vielen Dank. Also ist per Referenz vorzuziehen

    Wenn du die Besitzübertragung nicht brauchst, kannst du das machen. Aber dann könntest du auch gleich eine Referenz auf das Objekt übergeben, das am shared_ptr hängt.



  • if you have a shiny new hammer everything looks like a nail

    Dein "shiny new hammer" sind smart pointer?



  • Und dein rusty old hammer sind blöde Kommentare 🙄



  • TNA schrieb:

    DKlay schrieb:

    OK vielen Dank. Also ist per Referenz vorzuziehen

    Wenn du die Besitzübertragung nicht brauchst, kannst du das machen. Aber dann könntest du auch gleich eine Referenz auf das Objekt übergeben, das am shared_ptr hängt.

    Sorry, aber das ist Unsinn.

    Wenn man shared ownership braucht, dann braucht mans halt.
    Und man kann dabei natürlich auch nen shared_ptr const& übergeben. Die Funktion die auch "Mitbesitzer" werden will kopiert sich aus der Referenz eben einen eigenen** shared ** _ptr .



  • hustbaer schrieb:

    Wenn man shared ownership braucht, dann braucht mans halt.
    Und man kann dabei natürlich auch nen shared_ptr const& übergeben. Die Funktion die auch "Mitbesitzer" werden will kopiert sich aus der Referenz eben einen eigenen** shared ** _ptr .

    Wenn die Funktion wirklich "Mitbesitzer" werden will, sollte das optimalerweise schon aus der Signatur klar werden. Das übergeben "per value" hat dann auch den Vorteil, dass man move-Semantik ausnutzen kann.



  • knivil schrieb:

    if you have a shiny new hammer everything looks like a nail

    Dein "shiny new hammer" sind smart pointer?

    🕶 also ich arbeite mich gerade rein in C++, und klar es gibt Situation wo man smart pointer nicht braucht...aber die Frage hat mich brennend interessiert!



  • DKlay schrieb:

    Hallo,

    macht es Unterschied (bzgl. Performance) shared_ptr per Wert oder Referenz zu übergeben?

    Ja.

    Und die Antwort auf die Folgefrage "Wie soll ich einen shared_ptr übergeben? Per Wert oder Referenz?" ist "Kommt drauf an."

    Bei Typen, die leicht movable sind und wo das Kopieren teurer ist, verwende ich gerne pass-by-value, wenn ich mir damit u.U. eine Kopie sparen kann. Das kommt z.B. dann vor, wenn eine Funktion oder ein Konstruktor eine "Kopie" eines solchen Objekts irgendwo anders wegspeichern will. Beispiel:

    class foo
    {
    public:
        explicit foo(shared_ptr<bar> b)
        : c(move(b))
        {}
    private:
        shared_ptr<bar> c;
    };
    

    Das schöne hier ist, dass der Nutzercode explizit keine Kopie anlegt. Er "move't" nur b nach c . Das Kopieren wird hier dem Compiler überlassen. Der kann das ggf wegoptimieren oder auch den Move-Konstruktor bemühen, um b zu erzeugen. Gleiches gilt auch für viele andere Typen, std::string, std::vector<>, etc. Sie sind relativ billig move-bar und typischerweise teuer zu kopieren.

    Und wenn Du innerhalb der Funktion nur auf das Objekt zugreifen willst, worauf der shared_ptr zeigt, dann solltest Du wahrscheinlich direkt eine Referenz übergeben (ohne shared_ptr dazwischen):

    void foo(vector<int> & ref)
    {
       ...
    }
    
    void bar()
    {
       shared_ptr<vector<int>> sp = ...;
       foo(*sp);
    }
    

    Es mag aber auch Fälle geben, wo die Übergabe

    void foo(shared_ptr<vector<int>> const& ptr)
    

    sinnvoll ist. Da fällt mir zwar gerade nichts zu ein, aber ausschließen will ich das jetzt nicht.



  • aber ausschließen will ich das jetzt nicht.

    Angsthase 🙂

    klar es gibt Situation wo man smart pointer nicht braucht

    Das impliziert (fuer mich), dass der Gebrauch von smart pointer die Regel bzw. best practice ist und selten rohe Zeiger benutzt werden sollten. Dem widerspreche ich.



  • Wenn derjenige, der den Pointer übergeben bekommt, Besitz von der mit dem Pointer verbundenen Ressource ergreift, dann würde ich den Pointer per Wert übergeben, um dies im Interface auszudrücken. Wenn nicht, würde ich mich fragen, wieso überhaupt ein shared_ptr übergeben weden sollte...



  • TNA schrieb:

    Wenn die Funktion wirklich "Mitbesitzer" werden will, sollte das optimalerweise schon aus der Signatur klar werden.

    Wird es aber nicht.

    Wenn man nämlich Ownership-sharing nicht ermöglichen will, dann kann man der Funktion in den allermeisten Fällen nämlich gleich nen Raw-Pointer übergeben.



  • hustbaer schrieb:

    Wenn man nämlich Ownership-sharing nicht ermöglichen will, dann kann man der Funktion in den allermeisten Fällen nämlich gleich nen Raw-Pointer übergeben.

    Damit wäre ja dann alles beredet => shared_ptrs per value übergeben.
    Spart die Kopie, wenn direkt mit make_shared() als Argument aufgerufen, andernfälls hätte die Funktion sicher sowieso kopiert oder hätte andernfalls einen Raw-Pointer genommen und man spart sich das hässliche const& zu tippen, also Win & Win.



  • hustbaer schrieb:

    TNA schrieb:

    Wenn die Funktion wirklich "Mitbesitzer" werden will, sollte das optimalerweise schon aus der Signatur klar werden.

    Wird es aber nicht.

    Wenn man nämlich Ownership-sharing nicht ermöglichen will, dann kann man der Funktion in den allermeisten Fällen nämlich gleich nen Raw-Pointer übergeben.

    Oder eine Referenz, wie ich vorgeschlagen habe. Ich sehe halt nur keine wirklich sinnvolle Anwendung dafür, den shared_ptr per Referenz zu übergeben.



  • TNA schrieb:

    Ich sehe halt nur keine wirklich sinnvolle Anwendung dafür, den shared_ptr per Referenz zu übergeben.

    Eine Funktion, die vielleicht den shared_ptr irgendwo speichert oder vielleicht auch nicht.

    Z.B. ein Cache, der einen shared_ptr hält, wenn der noch nicht hinzugefügt wurde und aus irgendeinem Grund kein weak_ptr verwendet werden soll.


Anmelden zum Antworten