Smart Pointers vs Raw Pointers in Modern C++


  • Gesperrt

    Dieser Beitrag wurde gelöscht!

  • Gesperrt

    Dieser Abschnitt sagt glaube ich schon alles:

    In den meisten Fällen sollte man beim Initialisieren eines Rohzeigers oder Ressourcenhandles, der auf eine Ressource verweist, diesen sofort in einen Smartpointer umwandeln. In modernem C++ werden Rohzeiger nur noch in kleinen Codeblöcken mit begrenztem Gültigkeitsbereich, Schleifen oder Hilfsfunktionen verwendet, wo die Performance entscheidend ist und keine Verwechslungsgefahr bezüglich der Besitzverhältnisse besteht.


  • Gesperrt

    This is probably like "casting pearls before swine", but I've written a short example showing why you need smart pointers, and an example without smart pointers that illustrates how much more work it takes...

    (I'd like to apologize in advance for my "Denglisch".)

    #include <iostream>
    #include <memory>
    
    struct Punkt {
        int x;
        int y;
    };
    
    void korrigiereKoordinaten(Punkt& punkt) {
        if (punkt.x < 0) {
            punkt.x = 0;
        }
        if (punkt.y < 0) {
            punkt.y = 0;
        }
    }
    
    void verschieben(Punkt& punkt, int dx, int dy) {
        punkt.x += dx;
        punkt.y += dy;
    
        // After the shift, the coordinates were checked and corrected.
        korrigiereKoordinaten(punkt);
    }
    
    void ausgeben(const Punkt& punkt) {
        std::cout << "Punkt: (" << punkt.x << ", " << punkt.y << ")\n";
    }
    
    void hinweisOhneSmartPointer() {
        // A smart pointer is not strictly necessary if a pointer merely points to an existing object temporarily and does not take ownership of it. However, this raw pointer owns the memory itself.
        Punkt* rawPointer = new Punkt{10, 20};
    
        std::cout << "Punkt über Raw Pointer: ";
        ausgeben(*rawPointer);
    
        // With a raw pointer, the memory must be freed manually.
        delete rawPointer;
        rawPointer = nullptr;
    }
    
    int main() {
        // The point is automatically released as soon as the scope of validity ends.
        auto punkt = std::make_unique<Punkt>(Punkt{3, 4});
    
        hinweisOhneSmartPointer();
    
        std::cout << "Vor dem Verschieben: ";
        ausgeben(*punkt);
    
        verschieben(*punkt, 2, -1);
    
        std::cout << "Nach dem Verschieben: ";
        ausgeben(*punkt);
    
        // Without a smart pointer, you would have to call `delete` manually here. If there are multiple return paths or exceptions, this can easily lead to memory leaks. `std::unique_ptr` handles the deallocation safely.
    }
    

    "Scope of validity" here refers to the lifetime of the variable. In German, we sometimes use slightly altered terms.



  • @Anon-81275 checking now..


  • Mod

    In the end, the real answer is the rule of zero, that you are rarely ever going to need them. The one and only usecase is, that you are writing something that manages a resource. And then you use a smart pointer, no exceptions.

    Anon-81275s is rather artificial in that regard, as he is intentionally handling the object as if he were writing C. Which, of course, is much improved by the availability of a smart pointer, but you would never even write it anything like this in C++ in the first place.


  • Gesperrt

    @kavinreed

    Do you understand the concept now, or are you still testing it? Those are two different things.

    My example is also untested - that is, I haven't compiled it yet. So it could contain syntax errors.

    Unfortunately, I don't fully understand myself when one should use std::make_unique.


  • Gesperrt

    @SeppJ sagte in Smart Pointers vs Raw Pointers in Modern C++:

    Anon-81275s is rather artificial in that regard, as he is intentionally handling the object as if he were writing C.

    Why? Please explain.

    Edit: Ach, können ja auch auf Deutsch schreiben... Du meintest wegen der struct oder?



  • @Anon-81275 sagte in Smart Pointers vs Raw Pointers in Modern C++:

    @SeppJ sagte in Smart Pointers vs Raw Pointers in Modern C++:

    Anon-81275s is rather artificial in that regard, as he is intentionally handling the object as if he were writing C.

    Why? Please explain.

    Es gibt keinen guten Grund in dem Beispielcode einen besitzenden Pointer zu verwenden, das passiert dort nur um des Beispiels wegen. Gerade eine Variable, die man am Anfang einer Funktion erzeugt und am Ende wieder zerstört wäre eigentlich ein Paradebeispiel für eine automatische Variable. Daher "artifical" und eher etwas, das man in C sieht. Obwohl man da für diesen Code auch mit lokalen structs arbeiten könnte und kein malloc/free benötigt.


  • Gesperrt

    @Finnegan Kommt noch mehr Blödsinn? Ich hatte dich nicht gefragt.


  • Gesperrt

    Natürlich ist das Beispiel "künstlich". Wenn es nicht künstlich wäre, dann wäre es ja auch kein Beispiel mehr. 🤦♂


  • Mod

    Mach mal ein paar Tage Pause. Und dass ich (und so ziemlich jeder andere auch) auf technische Fragen von dir nicht antworte, sollte selbst in deinen Dickschädel eingedrungen sein. Du kannst dankbar sein, dass Finnega sich doch bemüht hat, dir deinen eigenen Code zu erklären

    PS: Oh, nein. Ich befürchte, du dachtest bis jetzt, dass niemand mit dir redet, weil du so furchtbar abgehobene Fragen stellst, dass niemand mithalten kann 🤦♂



  • @SeppJ Wenn ich nicht wüsste, dass sich hier auch ein paar ausgesprochene Experten tummeln, würde ich denken, das sei hier mittlerweile ein Psychotherapie- und KI-Test-Forum. Ich vermute mal, die ganzen Studenten, die hier vorher aufgeschlagen sind, fragen heute eher ein LLM. Wenn das mal auf Dauer gut geht. Irgendwann werden die Modelle nur noch mit anderen KI-generierten Informationen trainiert und entwickeln vielleicht ganz eigene Pathologien.


Anmelden zum Antworten