Sobes.tech
Middle

Kaip veikia unique_ptr C++-e?

sobes.tech AI

Atsakymas iš AI

std::unique_ptr — tai išmanusis rodyklis, kuris įgyvendina išskirtinę nuosavybę dinamiškai paskirstytam objektui. Jis užtikrina automatinį atminties valdymą: objektas, į kurį nurodo unique_ptr, automatiškai pašalinamas unique_ptr sunaikinimo metu.

Pagrindinės savybės:

  • Išskirtinė nuosavybė: Bet kuriuo metu tik vienas unique_ptr gali turėti konkretų objektą.
  • Kopijavimas draudžiamas: unique_ptr negali būti kopijuojamas. Tai užkerta kelią daugybiniam nuosavybei to paties objekto ir "dvigubo ištrynimo" problemai.
  • Perkėlimo semantika: Objekto nuosavybė gali būti perduodama iš vieno unique_ptr į kitą naudojant perkėlimo semantiką (std::move).
  • Konfigūruojamas ištrynėjas: Gali būti pateiktas savas ištrynėjas (deleter) valdyti specifinius išlaisvinimo būdus.

Veikimo principas grindžiamas RAII (Resource Acquisition Is Initialization): išteklius (dinamiškai paskirstytą atmintį) įgyjama kuriant objektą (unique_ptr) ir išlaisvinama sunaikinus tą objektą.

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

class MyClass {
public:
    MyClass() { std::cout << "MyClass sukurtas\n"; }
    ~MyClass() { std::cout << "MyClass sunaikintas\n"; }
};

int main() {
    {   
        // Sukurti `unique_ptr`, kuris valdo MyClass objektą
        std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>(); 
        
        // Šiuo metu ptr1 yra išskirtinis objekto savininkas
        // auto ptr2 = ptr1; // Klaida: kopijavimas draudžiamas

        // Nuosavybės perdavimas iš ptr1 į ptr2
        std::unique_ptr<MyClass> ptr2 = std::move(ptr1); 
        
        // Po perkėlimo ptr1 nebeturi objekto (tapo nullptr)
        if (!ptr1) {
            std::cout << "ptr1 neturi objekto: " << (ptr1 ? "Taip" : "Ne") << "\n";
        }

        // ptr2 pabaiga
        // ptr2 sunaikinamas, ir objektas MyClass, kurį jis valdo, automatiškai ištrinamas.
    } // MyClass objektas sunaikinamas čia

    std::cout << "main pabaiga.\n";

    return 0;
}

Palyginimas su raw pointer:

Charakteristika raw pointer std::unique_ptr
Nuosavybė Nenurodyta Išskirtinė
Automatinis ištrynimas Ne Taip
Kopijavimo semantika Taip Ne (tik perkėlimas)
Atminties nutekėjimai Aukštas rizikas Žemas rizikas

Apskritai, unique_ptr yra pageidaujamas būdas valdyti dinaminę atmintį C++11 ir naujesnėse versijose, kai reikalinga griežta nuosavybė ir automatinis išlaisvinimas.