Sobes.tech
Middle

Ինչպես է աշխատում unique_ptr-ը C++-ում?

sobes.tech AI

Պատասխան AI-ից

std::unique_ptr — դա խելացի ցուցիչ է, որը իրականացնում է բացառիկ սեփականություն դինամիկորեն հատկացված օբյեկտի վրա: Նա ապահովում է ավտոմատ հիշողության կառավարում. օբյեկտը, որի վրա ցույց է տալիս unique_ptr, ավտոմատ կերպով հեռացվում է unique_ptr ոչնչացման ժամանակ:

Հիմնական առանձնահատկությունները՝

  • Բացառիկ սեփականություն: Յուրաքանչյուր պահի միայն մեկ unique_ptr կարող է ունենալ կոնկրետ օբյեկտ:
  • Անհնար է կրկնօրինակել: unique_ptr-ը չի կարող կրկնօրինակվել: Սա կանխում է միաժամանակյա սեփականությունը նույն օբյեկտի վրա և "երկակի հեռացման" խնդիրը:
  • Տեղափոխության սիմանթիկա: Օբյեկտի սեփականությունը կարող է փոխանցվել մեկ unique_ptr-ից մյուսին std::move-ի միջոցով:
  • Կարգավորող հեռացնող: Կարող է տրամադրվել սեփական հեռացնող (deleter)՝ հատուկ ռեսուրսների ազատման մեթոդների կառավարման համար:

Աշխատանքի սկզբունքը հիմնված է RAII (Resource Acquisition Is Initialization) սկզբունքի վրա՝ ռեսուրսը (դինամիկ հատկացված հիշողությունը) ձեռք է բերվում օբյեկտի ստեղծման ժամանակ (unique_ptr) և ազատվում է այդ օբյեկտի ոչնչացման ժամանակ:

#include <memory> // unique_ptr-ի համար
#include <iostream>

class MyClass {
public:
    MyClass() { std::cout << "MyClass ստեղծված\n"; }
    ~MyClass() { std::cout << "MyClass ոչնչացված\n"; }
};

int main() {
    {   
        // Ստեղծում `unique_ptr`, որը տիրապետում է MyClass օբյեկտին
        std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>(); 
        
        // Այս պահին ptr1- ը բացառիկ տեր է օբյեկտի վրա
        // auto ptr2 = ptr1; // սխալ՝ կոդը չի compile-վի, քանի որ կրկնօրինակումն արգելված է

        // Տիրապետության փոխանցում ptr1-ից ptr2-ին
        std::unique_ptr<MyClass> ptr2 = std::move(ptr1); 
        
        // Փոխանցումից հետո ptr1- ը այլևս տիրապետում է օբյեկտին (դարձավ nullptr)
        if (!ptr1) {
            std::cout << "ptr1 օբյեկտի տեր չէ: " << (ptr1 ? "Այո" : "Ոչ") << "\n";
        }

        // ptr2- ի տիրապետության ժամկետը ավարտվում է
        // ptr2- ը ոչնչացվում է, և օբյեկտը ավտոմատ կերպով հեռացվում է
    } // MyClass օբյեկտը ոչնչացվում է այստեղ

    std::cout << "main-ի վերջը\n";

    return 0;
}

Համեմատություն raw pointer-ի հետ՝

Գծագիր raw pointer std::unique_ptr
Ռեսուրսի տիրապետում Չի սահմանվում Բացառիկ
Ավտոմատ հեռացում Չի Այո
Կոպիայի սիմանթիկա Այո Ոչ (միայն տեղափոխում)
Հիշողության լքումներ Բարձր ռիսկ Նվազ ռիսկ

Ընդհանուր առմամբ, unique_ptr-ը նախընտրելի միջոց է դինամիկ հիշողության կառավարման համար C++11 և ավելի բարձր տարբերակներում՝ երբ պահանջվում է խիստ սեփականություն և ավտոմատ ազատում ռեսուրսների։