Speicherverwaltung in C++



  • Hallo zusammen

    Ich hab ja von dem RAII-Konzept gehört und mir ist auch klar wie das funktioniert.
    Aber trotzdem fordern man ja auch schonmal Objekte in ner Methode an.
    Was mach ich denn, wenn ich in einer Methode ein Objekt erstelle?
    Gibt man dann immer einen auto_ptr zurück oder sollte man sowas auch vermeiden?
    Oder lieber das Objekt auf dem Stack anlegen und den Copy-Konstruktor in Anspruch nehmen?

    Jetzt aber noch ne andere theoretische Frage:
    Mal Angenommen ich hab ne Klasse die liefert ein MyClass* zurück.
    Das Objekt muss nicht gelöscht werden (wie man auch nicht erwarten würde)
    Jetzt überschreibe ich in einer abgeleiteten Klasse die Methode.
    Hier muss ich aber aus irgendwelchen Gründen ein neues Objekt zurückliefern.
    Hab ich da in C++ dann verloren oder gibt es da auch noch irgendeinen Trick?

    Gruß,
    *Cpp-Anfänger*



  • Cpp-Anfänger schrieb:

    Ich hab ja von dem RAII-Konzept gehört und mir ist auch klar wie das funktioniert.
    Aber trotzdem fordern man ja auch schonmal Objekte in ner Methode an.
    Was mach ich denn, wenn ich in einer Methode ein Objekt erstelle?
    Gibt man dann immer einen auto_ptr zurück oder sollte man sowas auch vermeiden?
    Oder lieber das Objekt auf dem Stack anlegen und den Copy-Konstruktor in Anspruch nehmen?

    auto_ptr ist zwar mitunter recht nützlich, aber nicht gerade das Idealbild eines Smart-Pointers - da dürften in vielen Fällen die Boost Pointerklassen (z.B. shared_ptr) besser ins Konzept passen.
    Ansonsten: Bei kleinen Objekten gehe ich lieber über eine Rückgabe per Wert, bei größeren Objekten suche ich meist nach Alternativen (z.B. eine const-Referenz auf ein bereits existierendes Objekt), um Kopier-Operationen zu minimieren.

    Jetzt aber noch ne andere theoretische Frage:
    Mal Angenommen ich hab ne Klasse die liefert ein MyClass* zurück.
    Das Objekt muss nicht gelöscht werden (wie man auch nicht erwarten würde)
    Jetzt überschreibe ich in einer abgeleiteten Klasse die Methode.
    Hier muss ich aber aus irgendwelchen Gründen ein neues Objekt zurückliefern.
    Hab ich da in C++ dann verloren oder gibt es da auch noch irgendeinen Trick?

    Dann solltest du dich darum kümmern, daß dieses neue Objekt auch nicht gelöscht werden muß 😉
    (aber ehrlich gesagt verstehe ich nicht ganz, worauf du mit diesem Szenario hinauswillst)



  • CStoll schrieb:

    auto_ptr ist zwar mitunter recht nützlich, aber nicht gerade das Idealbild eines Smart-Pointers - da dürften in vielen Fällen die Boost Pointerklassen (z.B. shared_ptr) besser ins Konzept passen.

    War der Hinweis auf die Boost-Pointer-Klassen hier eine allgemeine Anmerkung
    oder würdest du hier in bestimmten Fällen einen verwenden?
    Wenn ja, wann?





  • CStoll schrieb:

    auto_ptr ist zwar mitunter recht nützlich, aber nicht gerade das Idealbild eines Smart-Pointers

    Wieso? Sofern destructive copy semantics ausreichen, was bei Rückgabewerten aus Funktionen ja oftmals der Fall ist, ist auto_ptr doch ideal. Mehr braucht man dann auch nicht.



  • Ich versteh den Sinn von boost::scoped_ptr<T> nicht so ganz...
    Das kann doch der auto_ptr auch, oder seh ich das falsch?
    Oder ist boost::scoped_ptr<T> einfach performanter?

    scoped_ptr verbietet die bei auto_ptr mögliche Zuweisung (die einen u.U. gefährlichen, weil versteckten Transfer of Ownership bedeutet)

    Oder ist dieser Grund der Einzige?

    Gruß,
    *Cpp-Anfänger*



  • scoped_ptr gibt nie das Eigentum ab, auto_ptr schon (und das sogar, ohne dich darüber zu informieren). Und wenn du Pech hast, zerlegst du dir damit Objekte, die du noch brauchst:

    void print_out(auto_ptr<Typ> pdata)
    {
      cout<<*pdata;
    }
    /* Unerwünschter Nebeneffekt:
    pdata übernimmt das Eigentum von seinem Argument und löscht im Destruktor das
    Objekt, auf das er zeigt.*/
    

    Mit anderen Smart-Pointern wäre das nicht passiert (scoped_ptr hätte sich gar nicht compilieren lassen und shared_ptr erzeugt eine korrekte Semantik)

    @Groovemaster: Wichtig ist das "solange" 😉 Sobald die destruktive Copy-Semantik dir nicht mehr reicht, kannst du auto_ptr in die Tonne treten.



  • CStoll! Aber bei dir hört sich das so an, als ob es was schlechtes wäre, das auto_ptr immer nur einen Besitzer haben kann? Warum? Es ist schliesslich der Sinn von auto_ptr! ➡ "by design" nennt man sowas. scoped_ptr hat ein anderen dienlichen Zweck, mehr nicht.



  • Artchi schrieb:

    CStoll! Aber bei dir hört sich das so an, als ob es was schlechtes wäre, das auto_ptr immer nur einen Besitzer haben kann?

    Sorry, wenn das falsch rüberkam. Ich hab' nichts gegen das Konzept hinter dem auto_ptr<> - ich hab' nur etwas dagegen, daß manche Leute ihn als Universal-Heilmittel für alle Pointer-Probleme ansehen.



  • Dass man einem auto_pointer nicht das Objekt klaut ist doch klar, oder?
    Das ist ja so, als löscht man ein Objekt das man übergeben kriegt...



  • Cpp-Anfänger schrieb:

    Dass man einem auto_pointer nicht das Objekt klaut ist doch klar, oder?

    Zumindest SOLLTE es klar sein 😉
    Nur leider passiert es viel zu leicht, daß man es unbeabsichtigt doch macht - und der Compiler hat idR kein Problem damit.



  • CStoll schrieb:

    @Groovemaster: Wichtig ist das "solange" 😉 Sobald die destruktive Copy-Semantik dir nicht mehr reicht, kannst du auto_ptr in die Tonne treten.

    Schon klar. Es gibt ja auch nicht DEN Smart Pointer, sondern Verschiedene für den jeweils benötigten Zweck. Nur hörte es sich so an, als ob es weitaus bessere Smart Pointer als auto_ptr gibt. Für den Zweck, für den auto_ptr konzipiert ist, ist er aber vollkommen iO. Zudem hat er gegenüber boost::scoped_ptr keinerlei Overhead. Der entsteht ja erst beim Kopieren, was boost::scoped_ptr nicht unterstützt.


Log in to reply