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_ptrgali turėti konkretų objektą. - Kopijavimas draudžiamas:
unique_ptrnegali 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.