Sobes.tech
Senior

Hogyan valósítható meg egy okos mutató egy vagy több objektumhoz?

sobes.tech MI

Válasz az MI-től

Egy objektum esetén: unique_ptr vagy shared_ptr. Több objektum esetén: shared_ptr (közös tulajdonlás) vagy weak_ptr (figyelés anélkül, hogy részt venne az életciklus kezelésében).

#include <memory>
#include <vector>

// Objektum osztály példája
class MyObject {
public:
    MyObject() { /* Konstruktor */ }
    ~MyObject() { /* Destruktor */ }
};

// Egy objektumhoz: unique_ptr (egyedüli tulajdonlás)
void single_unique_ptr() {
    std::unique_ptr<MyObject> ptr = std::make_unique<MyObject>();
    // Az objektum automatikusan törlődik, amikor kilép a láthatósági körből
}

// Egy objektumhoz: shared_ptr (közös tulajdonlás)
void single_shared_ptr() {
    std::shared_ptr<MyObject> ptr = std::make_shared<MyObject>();
    // A tulajdonosok száma növekszik
    std::shared_ptr<MyObject> another_ptr = ptr;
    // Az objektum akkor törlődik, amikor az utolsó shared_ptr is megszűnik rá mutatni
}

// Több objektum esetén: vector shared_ptr-kkel
void multiple_shared_ptr() {
    std::vector<std::shared_ptr<MyObject>> objects;
    objects.push_back(std::make_shared<MyObject>());
    objects.push_back(std::make_shared<MyObject>());
    // Minden objektum a saját shared_ptr-je által van kezelve a vektorban
    // Az objektumok törlődnek, amikor a megfelelő shared_ptr-k is megszűnnek
}

// Több objektum esetén: vector unique_ptr-kkel
void multiple_unique_ptr() {
    std::vector<std::unique_ptr<MyObject>> objects;
    objects.push_back(std::make_unique<MyObject>());
    objects.push_back(std::make_unique<MyObject>());
    // Ebben az esetben a vektor birtokolja az egyedi mutatókat
    // Az objektumok törlődnek, amikor a vektor kilép a láthatósági körből

    // Megjegyzés: a unique_ptr-t nem lehet másolni, csak mozgatni (move)
    std::unique_ptr<MyObject> moved_ptr = std::move(objects[0]);
}

A unique_ptr és a shared_ptr összehasonlítása:

Jellemző std::unique_ptr std::shared_ptr
Tulajdonlás Egyedüli Közös (hivatkozásszámlálóval)
Másolás Nem (csak áthelyezés) Igen
Teljesítmény Kicsit gyorsabb (nincs hivatkozásszámláló overhead) Kicsit lassabb (hivatkozásszámláló)
Ciklikus hivatkozások Nem védett Memóriaszivárgáshoz vezethet (weak_ptr szükséges)

std::weak_ptr használható egy shared_ptr által kezelt objektum megfigyelésére anélkül, hogy növelné a hivatkozásszámot, így elkerülve a ciklikus hivatkozási problémákat.

#include <memory>

class Node {
public:
    std::shared_ptr<Node> next;
    std::weak_ptr<Node> previous; // weak_ptr használata a ciklikus hivatkozás elkerülésére

    Node() = default;
    ~Node() { /* Destruktor */ }
};

void weak_ptr_example() {
    std::shared_ptr<Node> node1 = std::make_shared<Node>();
    std::shared_ptr<Node> node2 = std::make_shared<Node>();

    node1->next = node2;
    node2->previous = node1; // weak_ptr használata

    // shared_ptr-t lehet szerezni a weak_ptr-ből az objektum eléréséhez
    if (std::shared_ptr<Node> locked_node = node2->previous.lock()) {
        // Ha az objektum még él
        // ... dolgozunk a locked_node-dal
    } else {
        // Az objektum már törölve lett
    }
}