Was haltet ihr von unique_ptr als Ersatz für rohe Zeiger?



  • Ich habe gelesen, dass man auf die rohen Zeigen verzichten soll wo es nur geht. Da durch eine Exception auch mal gerne ein delete unbeabsichtigt ausgelassen werden kann. Wenn ich hier Mist erzähle, bitte korrigieren.

    Auf der Suche nach einer Alternative bin ich nun auf den unique_ptr als Alternative gestoßen. Was haltet ihr von dieser Alternative zu rohen Zeigern?


  • Mod

    Kommt drauf an wofür.

    Für besitzende Zeiger: Ja, auf jeden Fall irgendeinen geeigneten Smartpointer benutzen. Wenn man vorher einen rohen Zeiger benutzen wollte, ist unique_ptr ein wahrscheinlicher Kandidat für den richtigen Smartpointertyp.

    Für unbesitzende Zeiger: Unsinn.

    P.S.: Die Begründung mit den Exceptions finde ich ein bisschen zu kurz. Ich würde sagen: Weil es möglich ist, mit rohen besitzenden Zeigern fehlerhafte Freigaben zu erzeugen. Das sind ja nicht nur Exceptions, sondern auch (andere) Fehler/Unachtsamkeiten durch den Programmierer, die hier zum Fehler führen können. Bei den Smartpointern ist es gar nicht möglich, etwas falsch zu machen. Das auch noch ganz ohne jede Laufzeitkosten und auch praktisch ohne Kosten zur Compilezeit gegenüber einer gleichwertigen Variante mit rohen Zeigern. Also gibt es keinen Grund, jemals einen besitzenden Zeiger nicht smart zu machen.



  • Grasshopper schrieb:

    Ich habe gelesen, dass man auf die rohen Zeigen verzichten soll wo es nur geht.

    Das hast du falsch verstanden.

    Grasshopper schrieb:

    Da durch eine Exception auch mal gerne ein delete unbeabsichtigt ausgelassen werden kann.

    Besitzende Zeiger sind etwas anderes. (Nicht syntaktisch, aber semantisch.)

    Grasshopper schrieb:

    Wenn ich hier Mist erzähle, bitte korrigieren.

    Mission complete.

    Grasshopper schrieb:

    Auf der Suche nach einer Alternative bin ich nun auf den unique_ptr als Alternative gestoßen. Was haltet ihr von dieser Alternative zu rohen Zeigern?

    unique_ptr modelliert einen Zeiger, der alleiniger Besitzer (daher unique) des Objekts/der Objekte ist, auf die er zeigt. Wenn das die Situation ist die vorliegt, dann nutze unique_ptr.



  • Puh kompliziert fest zu machen was ich eigentlich meine^^ Also, mir geht es um rohe Zeiger(A* myA = new A()) die ich dann per new mit der Adresse meine Objektes füttere. Das habe ich wirklich falsch verstanden, dass man diese rohen Zeiger vermeiden sollte wo es nur geht?

    EDIT: Ich glaube, laut eurer Definition, besitzende Zeiger. Auch wenn mir der Unterschied nicht ganz klar ist. Denn ein roher Zeiger speichert immer nur eine Adresse.



  • int a;
    int* zeigend = &a;
    
    int* zeigendUndBesitzend = new int;
    


  • Grasshopper schrieb:

    Das habe ich wirklich falsch verstanden, dass man diese rohen Zeiger vermeiden sollte wo es nur geht?

    Nein 😉

    Also nochmals:

    // Besitzende Zeiger, die manuelle Speicherverwaltung erfordern
    MyClass* p = new MyClass();
    delete p;
    
    // Bessere Alternative: Unique Pointer
    std::unique_ptr<MyClass> q(new MyClass());
    
    // Nicht-besitzende, passive Zeiger, die als reine Verweise dienen
    // Völlig okay, kannst du auch weiterhin benutzen
    MyClass x;
    MyClass* r = &x;
    


  • Ah ok, deswegen syntaktisch kein Unterschied aber von der Art wie mit umzugehen ist.

    EDIT: Also werde ich jetzt anstellen rohe besitzende Zeiger std::unique_ptr einsetzen.



  • Grasshopper schrieb:

    EDIT: Also werde ich jetzt anstellen rohe besitzende Zeiger std::unique_ptr einsetzen.

    Schon mal 👍 , aber noch verbesserungsfähig.

    Es gibt verschiedene Zeiger für verschiedene Bedürfnisse. Sieh sie dir alle an.
    Dazu gibt es noch Boosts Pointer Container, die sind auch klasse.



  • Sone schrieb:

    Grasshopper schrieb:

    EDIT: Also werde ich jetzt anstellen rohe besitzende Zeiger std::unique_ptr einsetzen.

    Schon mal 👍 , aber noch verbesserungsfähig.

    Es gibt verschiedene Zeiger für verschiedene Bedürfnisse. Sieh sie dir alle an.
    Dazu gibt es noch Boosts Pointer Container, die sind auch klasse.

    Die können nicht mit unique_ptr umgehen.
    Standard-Container können das aber.



  • TyRoXx schrieb:

    Sone schrieb:

    Grasshopper schrieb:

    EDIT: Also werde ich jetzt anstellen rohe besitzende Zeiger std::unique_ptr einsetzen.

    Schon mal 👍 , aber noch verbesserungsfähig.

    Es gibt verschiedene Zeiger für verschiedene Bedürfnisse. Sieh sie dir alle an.
    Dazu gibt es noch Boosts Pointer Container, die sind auch klasse.

    Die können nicht mit unique_ptr umgehen.
    Standard-Container können das aber.

    Wovon redest du? Ich hab doch überhaupt nicht davon gesprochen, dass sie das sollen.



  • TyRoXx schrieb:

    Die können nicht mit unique_ptr umgehen.

    Sollen sie auch nicht. Die Zeiger werden bei Boost.PtrContainer weitgehend wegabstrahiert, sodass man normal darüber iterieren oder Algorithmen anwenden kann.


Log in to reply