eigenes Objekt überschreiben



  • Hi,

    ich habe eine Bildklasse die ein rotate() Methode hat. Da die rotate-Funktion nicht in-place ist, hab ich mir gedacht ich erstell ein neues Bildobjekt, schreib da das neue Bild rein und überschreib dann das aktuelle Objekt mit dem neuen.
    Ungefähr so:

    void Bild::rotate(int deg)
    {
       //rotieren...
       Bild NeuesBild;
       //rotieren...
    
       //this = &NeuesBild; //error: non-lvalue in assignment
       *this = NeuesBild; //kein Kompilierfehler
    }
    

    Allerdings bin ich mir jetzt nicht sicher, was für Fehler so auftreten können.
    Oder macht man sowas ganz anders?

    MfG Caster



  • Sofern der Kopierkonstruktor keine Probleme macht, sollte das so schon funktionieren. Auch wenn ich es ein wenig übertrieben finde jedesmal, wenn du eine Rotation machst ein neues Bild zu erzeugen. (Kommt allerdings auf deine Möglichkeiten an, ob du das wirklich so machen musst..)



  • Jetzt hab ich aber immer noch ein Problem. Das eigentliche Bild ist eine Bitmap in einem dynamisch angelegtem Speicher. Ich hab keinen Kopier- bzw. in dem Fall eher Zuweisungsoperator (oder?) implementiert, da ich mir gedacht hab, dass es langt wenn ich den Zeiger auf den Speicher kopier, da ich das neu angelegte Objekt ja nicht mehr benötige. Allerdings wird nach nach der Zuweisung (der Überschreibung des alten Objektes) der Destruktor des neuen Objektes aufgerufen, da dieses ja innerhalb dieser Funktion instanziert wurde. Der Destruktor "free'd" jetzt aber den Speicher auf den der (kopierte) Zeiger weist und das neu erzeugt Bild ist somit weg.
    Kann ich den Aufruf des Desktruktors irgendwie verhindern?

    MfG Caster

    EDIT: Mir fällt grad ein, ich könnte ja einfach die Instanzen zählen und erst nach der letzen den Speicher freimachen.



  • Caster schrieb:

    Jetzt hab ich aber immer noch ein Problem. Das eigentliche Bild ist eine Bitmap in einem dynamisch angelegtem Speicher. Ich hab keinen Kopier- bzw. in dem Fall eher Zuweisungsoperator implementiert, da ich mir gedacht hab, dass es langt wenn ich den Zeiger auf den Speicher kopier, da ich das neu angelegte Objekt ja nicht mehr benötige. Allerdings wird nach nach der Zuweisung (der Überschreibung des alten Objektes) der Destruktor des neuen Objektes aufgerufen, da dieses ja innerhalb dieser Funktion instanziert wurde. Der Destruktor "free'd" jetzt aber den Speicher auf den der (kopierte) Zeiger weist und das neu erzeugt Bild ist somit weg.
    Kann ich den Aufruf des Desktruktors irgendwie verhindern?

    MfG Caster

    Statt dessen solltest du eher einen korrekten Copy-Ctor/Assignment Operator implementieren, der tatsächlich die Daten auch kopiert. Dein Ansatz mit dem verhindern des Destruktoraufrufs ist völlig falsches Design.



  • Aber so würde ich umsonst ein vl. 1MB großes Bild kopieren.
    Und zu der Sache mit dem Instanzen zählen: da müsste ich das inkrementieren des Zählers ja auch in dem Zuweisungsoperator machen und den Standard-Zuweisungoperator wieder selber implementieren... oh man.



  • Wenn Du ein natürliches Design ohne Referenzzählung haben möchtest, wie wäre folgendes:

    • eine Methode void Bild::swap(Bild& other) , die nur den Bilddatenzeiger mit other tauscht
    • void rotate(Bild& bild, int deg) ist eine freie Funktion, die ein neues Bild anlegt, das Rotationsergebnis dort ablegt und dann bild.swap(neuesBild) macht (den swap mit this finde ich - komisch)
    • (opt.) der Copy-Ctor kopiert das gesamte Bild (tiefe Kopie)
    • (opt.) der Zuweisungsoperator nutzt Copy-and-Swap (s.a. Google)

    Die letzten beiden Punkte würden das Gesamtild imho noch abrunden, natürliches Kopierverhalten eben (es seidenn Du möchtest Referenzzählung, dann nimm am besten gleich std::tr1::shared_ptr 🙂 ).



  • Ich hab mit jetzt mal den Quellcode von "CxImage" angeschaut und die machen das eigentlich auch nicht viel anders als ich; nur sie rufen manuell eine Destroy-Methode auf anstatt den Speicher im Destruktor freizugeben.

    @LordJaxom: Deine Idee ist aber auch nicht schlecht.


Anmelden zum Antworten