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_ptromada 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.