Sobes.tech
Middle

Hogyan működik a unique_ptr C++-ban?

sobes.tech MI

Válasz az MI-től

std::unique_ptr — ez egy okos mutató, amely megvalósítja egy dinamikusan allokált objektum kizárólagos tulajdonjogát. Automatikus memória kezelést biztosít: a unique_ptr által mutatott objektum automatikusan törlődik a unique_ptr megsemmisítésekor.

Fő jellemzők:

  • Kizárólagos tulajdonjog: Bármikor csak egy unique_ptr lehet egy adott objektum tulajdonosa.
  • Másolás hiánya: A unique_ptr nem másolható. Ez megakadályozza az ugyanazon objektum több tulajdonosát és a "kettős törlés" problémáját.
  • Mozgatási szemantika: Az objektum tulajdonjoga átadható egyik unique_ptr-ről a másikra a std::move segítségével.
  • Beállítható törlő: Saját törlőt adhat meg, hogy kezelje a források felszabadításának speciális módjait.

A működési elv RAII (Resource Acquisition Is Initialization) alapon nyugszik: a forrás (dinamikusan allokált memória) az objektum létrehozásakor kerül megszerzésre (unique_ptr), és a megsemmisítéskor szabadul fel.

#include <memory> // unique_ptr-hez
#include <iostream>

class MyClass {
public:
    MyClass() { std::cout << "MyClass létrehozva\n"; }
    ~MyClass() { std::cout << "MyClass megsemmisítve\n"; }
};

int main() {
    {   
        // Egy unique_ptr létrehozása, amely egy MyClass objektumot birtokol
        std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>(); 
        
        // Jelenleg, a ptr1 az objektum kizárólagos tulajdonosa
        // auto ptr2 = ptr1; // Fordítási hiba: másolás tiltott

        // Tulajdonjog átvitele ptr1-től ptr2-hez
        std::unique_ptr<MyClass> ptr2 = std::move(ptr1); 
        
        // A mozgás után, a ptr1 már nem birtokolja az objektumot (nullptr lesz)
        if (!ptr1) {
            std::cout << "ptr1 nem birtokol objektumot: " << (ptr1 ? "Igen" : "Nem") << "\n";
        }

        // A ptr2 élettartama itt ér véget.
        // A ptr2 megsemmisül, és az általa birtokolt MyClass objektum automatikusan törlődik.
    } // A MyClass objektum itt törlődik

    std::cout << "main vége.\n";

    return 0;
}

Összehasonlítva a raw pointer-rel:

Jellemző raw pointer std::unique_ptr
Forrás tulajdonjoga Nem meghatározott Kizárólagos
Automatikus törlés Nem Igen
Másolási szemantika Igen Nem (csak mozgás)
Memóriaszivárgás kockázata Magas Alacsony

Általánosságban, a unique_ptr az elsődleges módszer a dinamikus memória kezelésére C++11 és újabb verziókban, amikor szigorú tulajdonjog és automatikus erőforrás felszabadítás szükséges.