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
}
}