Zeiger = 0;



  • Ich persönlich würde auch 0-Zeigern einen Storage mit einem 0-Zeiger als Pointer sowie einem Refcount von 1 geben, das beseitigt ein paar Sonderbehandlungen. Ansonsten fehlt das "return *this;" in deinem Zuweisungsoperator und dein get() sowie die beiden überladenen Pointer-Operatoren sollten const sein. 😉
    Und swap kannste über std::swap implementieren.



  • War ja nur kurz heruntergetippt. 😉
    std::swap ist bewusst nicht drin, da STL.



  • Kellerautomat schrieb:

    Ich persönlich würde auch 0-Zeigern einen Storage mit einem 0-Zeiger als Pointer sowie einem Refcount von 1 geben, das beseitigt ein paar Sonderbehandlungen.

    Massive Performance-Verschwendung.



  • Warum wird der Destruktur beim verlassen des Blocks nicht aufgerufen?!

    Ich meine:

    int main(void)
    {
        int Integer = 4;
        std::cout << "Integer = " << Integer << "\n";
    
        //wir rufen hier ja auch nicht den Destruktor manuell auf?
        return 0;
    }
    

    Warum muss das bei Zeigern denn gemacht werden? Das verstehe ich nicht, könnte es mir jemand genauer erklären?



  • Nun ja, der Zeiger wird beim Verlassen des Scopes ordnungsgemäß zerstört, wie du es von Integern kennst. Aber wieso sollte dabei das Objekt, auf das gezeigt wird, zerstört werden?



  • Nicht zu fassen was für eine bescheuerte Diskussion hier geführt wird bezüglich delete . Einfach nicht zu fassen. Da fehlen mir die Worte.

    Vielleicht hilft das weiter: Ein Zeiger ist nur eine Zahl, die angibt, wo das Objekt im Speicher zu finden ist. new reserviert dir Platz für ein Objekt und gibt dir einen Zeiger, um das Objekt zu benutzen. Wenn du es nicht mehr brauchst, solltest du delete benutzen, um den Platz des Objektes wieder freizugeben.
    Ein Zeiger an sich tut gar nichts und wird automatisch zerstört, wie andere Primitive Typen wie z. B. int auch.



  • TyRoXx schrieb:

    Nicht zu fassen was für eine bescheuerte Diskussion hier geführt wird bezüglich delete . Einfach nicht zu fassen. Da fehlen mir die Worte.

    Eigentlich ging die Diskussion hauptsächlich um das if vor dem delete . Aber du darfst mir gerne verraten, was dich so fassungslos gemacht hat.



  • hustbaer schrieb:

    Massive Performance-Verschwendung.

    Wie oft hat man denn Nullzeiger?



  • TyRoXx schrieb:

    Nicht zu fassen was für eine bescheuerte Diskussion hier geführt wird bezüglich delete . Einfach nicht zu fassen. Da fehlen mir die Worte.

    Vielleicht hilft das weiter: Ein Zeiger ist nur eine Zahl, die angibt, wo das Objekt im Speicher zu finden ist. new reserviert dir Platz für ein Objekt und gibt dir einen Zeiger, um das Objekt zu benutzen. Wenn du es nicht mehr brauchst, solltest du delete benutzen, um den Platz des Objektes wieder freizugeben.
    Ein Zeiger an sich tut gar nichts und wird automatisch zerstört, wie andere Primitive Typen wie z. B. int auch.

    Sehr gute Antwort, danke!

    Theoretisch wäre das die richtige Lösung:

    class Data;
    
    class Pointer
    {
    private:
    
        Data* data
    
    public:
    
        Pointer(Data& d)
        {
            data = new Data(d);
        }
    
        free_memory()
        {
            delete data;
        }
    };
    
    int main(void)
    {
        Data d;
        Pointer* p = new Pointer(d);
    
        p->free_memory();
    
        return 0;
    }
    


  • @Kellerautomat
    Ach, recht oft eigentlich.
    z.B. jedes mal wenn man den Zeiger default-konstruiert und danach erst zuweist.
    Manchmal hat man auch optionale "Teile" in einem Objekt.

    Und davon abgesehen ist es praktisch wenn der Default-Konstruktor von solchen Klassen no-throw ist.



  • Hm, vielleicht haste wirklich Recht, ok.
    Wirklich überzeuugt hat mich das no-throw Argument. Andererseits finde ich es auch seltsam, wenn folgendes Konstrukt etwas werfen könnte:

    vector<shared_ptr<int>> v(100);
    v[42] = new int; // kein Speicher mehr für interne Verwaltungsdaten, kabumm. int geleakt.
    

  • Mod

    Kellerautomat schrieb:

    Hm, vielleicht haste wirklich Recht, ok.
    Wirklich überzeuugt hat mich das no-throw Argument. Andererseits finde ich es auch seltsam, wenn folgendes Konstrukt etwas werfen könnte:

    vector<shared_ptr<int>> v(100);
    v[42] = new int; // kein Speicher mehr für interne Verwaltungsdaten, kabumm. int geleakt.
    

    Dann muss der Zuweisungsoperator im Fehlerfall delete aufrufen. Bei std::shared_ptr geht das sowieso nur über den Konstruktor

    template<class Y> explicit shared_ptr(Y* p);
    ...
    7 Exception safety: If an exception is thrown, delete p is called.



  • Im russischen gibt es solch ein Sprichwort: "jeder spricht darüber, was ihm weh tut" und antwortet nicht auf die Frage des anderen.

    Meine Frage war, wie ich das ohne diesen ganzen Schnick-Schnack ganz simpel geregelt bekomme.

    oben habe ich ein korrigiertes Code-Stück aufgetipt wenn ihr das noch nicht bemerkt habt:

    class Data; 
    
    class Pointer 
    { 
    private: 
    
        Data* data 
    
    public: 
    
        Pointer(Data& d) 
        { 
            data = new Data(d); 
        } 
    
        free_memory() 
        { 
            delete data; 
        } 
    }; 
    
    int main(void) 
    { 
        Data d; 
        Pointer* p = new Pointer(d); 
    
        p->free_memory(); 
    
        return 0; 
    }
    

    Beide Pointer werden ordnungsgemäß gelöscht und deren Inhalt am Ende geleert, müsste doch korrekt funktionieren?



  • RussianTux schrieb:

    Beide Pointer werden ordnungsgemäß gelöscht und deren Inhalt am Ende geleert, müsste doch korrekt funktionieren?

    Ich sehe da zwei new und nur ein delete .



  • @RussianTux: Du baust dir doch gerade selbst einen Smartpointer nach, nur viel viel schlechter. Das ist kein Schnick-Schnack, vertrau doch den erfahrenen Leuten hier. Du löschst das Pointer-Objekt nicht und dadurch, dass du free_memory aufrufen musst, ist das ganze auch nicht Exception-save.



  • TyRoXx schrieb:

    RussianTux schrieb:

    Beide Pointer werden ordnungsgemäß gelöscht und deren Inhalt am Ende geleert, müsste doch korrekt funktionieren?

    Ich sehe da zwei new und nur ein delete .

    Ups, mein Fehler, korrigiere ich mal eben:

    class Data; 
    
    class Pointer 
    { 
    private: 
    
        Data* data 
    
    public: 
    
        Pointer(Data& d) 
        { 
            data = new Data(d); 
        } 
    
        free_memory() 
        { 
            delete data; 
        } 
    }; 
    
    int main(void) 
    { 
        Data d; 
        Pointer* p = new Pointer(d); 
    
        p->free_memory(); 
        delete p;
    
        return 0; 
    }
    


  • Was bringt dir die Pointer -Klasse, wenn sie nicht automatisch aufräumt?

    Wenn man free_memory() explizit aufrufen muss, kann man genauso gut delete verwenden. Dadurch gewinnst du absolut nichts.



  • Die ordentliche Lösung ohne Schnickschnak wäre std::unique_ptr.



  • Nexus schrieb:

    Was bringt dir die Pointer -Klasse, wenn sie nicht automatisch aufräumt?

    Wenn man free_memory() explizit aufrufen muss, kann man genauso gut delete verwenden. Dadurch gewinnst du absolut nichts.

    а мне блеать нахуй не надо автоматики тупорылые немецкие сущности

    Ich habe nie erwähnt dass ich Automatik brauche?!

    Der Aufruf von free_memory() sollte den Konstruktor von 'Data d' aufrufen und den Speicher bereinigen?!



  • RussianTux schrieb:

    Ich habe nie erwähnt dass ich Automatik brauche?!

    Ok, dann bringt die ganze Pointer -Klasse erst recht nichts.

    RussianTux schrieb:

    Der Aufruf von free_memory() sollte den Konstruktor von 'Data d' aufrufen und den Speicher bereinigen?!

    Du meinst Destruktor. Aber dafür reicht auch delete , dann hast du wenigstens nicht diese willkürliche Asymmetrie zwischen Anforderung und Freigabe.


Anmelden zum Antworten