Sobes.tech
Middle

Kuidas töötab unique_ptr C++-s?

sobes.tech AI

Vastus AI-lt

std::unique_ptr — see on nutikas näitaja, mis rakendab eksklusiivset omandit dünaamiliselt eraldatud objekti üle. See tagab automaatse mälu haldamise: objekt, millele unique_ptr viitab, eemaldatakse automaatselt unique_ptr hävitamisel.

Peamised omadused:

  • Eksklusiivne omand: Igas hetkel võib ainult üks unique_ptr omada konkreetset objekti.
  • Kopeerimine on keelatud: unique_ptr-i ei saa kopeerida. See takistab mitmekordset omandit sama objekti üle ja "topeltkustutamise" probleemi.
  • Liikumise semantika: Objekti omandit saab ühelt unique_ptr-lt teisele üle anda, kasutades liikumise semantikat (std::move).
  • Seadistatav kustutaja: Võib määrata oma kustutaja (deleter), et hallata spetsiifilisi ressursside vabastamise viise.

Tööpõhimõte põhineb RAII-l (Resource Acquisition Is Initialization): ressurss (dünaamiliselt eraldatud mälu) omandatakse objekti loomisel (unique_ptr) ja vabastatakse selle hävitamisel.

#include <memory> // `unique_ptr`
#include <iostream>

class MyClass {
public:
    MyClass() { std::cout << "MyClass loodud\n"; }
    ~MyClass() { std::cout << "MyClass hävitatud\n"; }
};

int main() {
    {   
        // `unique_ptr` loomine, mis omab MyClass objekti
        std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>(); 
        
        // Praegu on ptr1 objekti eksklusiivne omanik
        // auto ptr2 = ptr1; // Viga: kopeerimine on keelatud

        // Omandi üleandmine ptr1-lt ptr2-le
        std::unique_ptr<MyClass> ptr2 = std::move(ptr1); 
        
        // Pärast liikumist ei omanda ptr1 objekti (muutub nullptr-ks)
        if (!ptr1) {
            std::cout << "ptr1 ei omanda objekti: " << (ptr1 ? "Jah" : "Ei") << "\n";
        }

        // ptr2 lõpeb
        // ptr2 hävitatakse ja objekt MyClass, mida ta omab, eemaldatakse automaatselt.
    } // MyClass objekt hävitatakse siin

    std::cout << "main lõpeb.\n";

    return 0;
}

Võrdlus raw pointer-iga:

Omadus raw pointer std::unique_ptr
Ressursi omandamine Ei ole määratletud Eksklusiivne
Automaatne kustutamine Ei Jah
Kopeerimise semantika Jah Ei (ainult liikumine)
Mälu lekked Kõrge risk Madal risk

Üldiselt on unique_ptr eelistatud viis dünaamilise mälu haldamiseks C++11 ja uuemates versioonides, kui on vaja ranget omandit ja automaatset ressursside vabastamist.