Pointer-Problem?



  • Wenn du schon weißt, wie die Lösung aussieht, warum fragst du dann noch?

    Und ohne Smart-Pointer bleibt dir nichts anderes übrig, als die Kopier-Operationen auch zu definieren - entweder du kopierst den gesamten Block, den die Load()-Funktion reserviert hat, oder du zählst mit, wieviele Objekte diesen Block nutzen. (möglich sind auch Zwischenlösungen, bei denen du erst kopierst, wenn eins der Objekte den Speicherbereich ändern will)



  • Die Lösung kenne ich noch nicht, ich weis aber sehr genau wie ich es nicht lösen möchte ;).
    Meinst du damit dass ich dann z.B. den =-Operator überschreiben muss? Das wäre aus meiner Sicht die einfachste Lösung.



  • Ja, genau den mußt du überschreiben - und den Kopier-Konstruktor ( Test::Test(const Test& src); ).

    (das meinte ich dort oben mit den "Großen Drei" - Destruktor, Zuweisung und Kopier-Konstruktor treten grundsätzlich im Team auf.



  • Alles klar, dann werde ich es mal so probieren. Danke euch.



  • C/C++ schrieb:

    Jungs, das ist nur ein Beispielprogramm. Der wirkliche Code sieht ganz anders aus.

    Warum führst du die Leute dann mit falschem Code aufs Glatteis?



  • Ich habe halt ein Minimal-Beispiel gepostet damit man den Fehler schnell nachvollziehen kann und ihr euch nicht durch unnötig viel Code wälzen müsst. Leider bekommt man hier immer erstmal 5 Posts die dann irgendwelche anderen Dinge im Code bemängeln was auch nicht verkehrt ist, habe schließlich so schon mehrere hilfreiche Tipps hier im Forum bekommen.



  • So, habe jetzt mal versucht das ganze zu implemtieren, allerdings fürchte ich das wird so nicht funktionieren. Denn anstatt eines Int-Zeigers ist der Zeiger vom Typ Base und kann auch auf von Base abgeleitete Objekte zeigen was das Kopieren des Objects im Kopiekonstructor wohl unmöglich macht? Ich habe auch mal versucht anstatt einem Zeiger das Object selber zu nehmen, allerdings wurden dann bei virtuellen Funktionen nur noch die der Base-Klasse aufgerufen. Dann werde ich wohl doch Smart-Pointer brauchen.



  • Wenn du dein komplettes abgeleitetes Objekt kopieren willst, dann sollte das Objekt das besser selber machen - normalerweise in Form einer virtuellen clone()-Methode.
    Alternativ verwendest du Referenzzählung (d.h. die Kopien verwenden das selbe Objekt und erst der letzte kümmert sich darum, es wieder zu vernichten).



  • Das mit dem Copy-Konstruktor ist nicht so einfach. Zuerst einmal sind dort 2 Klassen beteiligt. Einmal der (Ich nenn ihn mal) Handler - Das ist die Klasse die den pointer enthält. Und einmal die Base, von der die realen Klassen abgeleitet werden. Damit das richtig funktioniert benötigt der Handler Copy-Konstruktor, Zuweisung und Destruktor. Der Rest geht dann nicht automatisch. Für das Kopieren fügt man der Klasse Base eine virtuelle Funktion (z.B. "Copy") hinzu, was eine mit new erzeugte Kopie von sich selbst zurück gibt.

    class Handler
    {
        ....
    
        Handler(const Handler & source)
        {
            pointer = source.pointer->Copy();
        }
    
        ....
        Base * pointer;
    };
    
    class Base
    {
        ...
    
        virtual Base * Copy() = 0;
    
        ...
    };
    
    class Real : public Base
    {
        ...
    
        virtual Base * Copy()
        {
            return new Real(*this);
        };
    
        ...
    };
    

    Das kann natürlich noch etwas sauberer ausgeführt werden ...



  • Mit Smart-Pointers, die intelligent genug sind, kann man auch polymorph kopieren. Dann kann man sich das intrusive Clone-Idiom sparen.


Anmelden zum Antworten