Sobes.tech
Middle

Ինչ եք գիտակցում C++-ում խելացի ցուցիչների մասին?

sobes.tech AI

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

Խելացի ցուցիչներ - դա RAII-օղակներ են սովորական (կեղտոտ) ցուցիչների վրա C++-ում, որոնք ապահովում են ավտոմատ կառավարման ժամանակը հատկացված հիշողության, կանխելով արտահոսքերը:

Հիմնական տեսակները C++ ստանդարտ գրադարանում:

  • std::unique_ptr
  • std::shared_ptr
  • std::weak_ptr

std::unique_ptr

  • Ունեցում է ռեսուրսը բացառիկ կերպով:
  • Չի կարող պատճենվել, բայց կարող է տեղափոխվել:
  • Օգտագործվում է ռեսուրսի միակ սեփականության համար:
  • Ծախսերը նվազագույն են, համարժեք են կեղտոտ ցուցակին:
// unique_ptr օրինակ
#include <memory>
#include <iostream>

int main() {
    std::unique_ptr<int> ptr = std::make_unique<int>(10);
    std::cout << *ptr << std::endl; // 10
    // std::unique_ptr<int> ptr2 = ptr; // Կոմպիլյատորային սխալ: unique_ptr-ները պատճենվում չեն
    std::unique_ptr<int> ptr3 = std::move(ptr); // Տեղափոխում սեփականության
    std::cout << *ptr3 << std::endl; // 10
    // std::cout << *ptr << std::endl; // Անորոշ վարքագիծ: ptr այժմ դատարկ է
    return 0;
}

std::shared_ptr

  • Թույլ է տալիս միաժամանակ մի ռեսուրսի մի քանի ցուցիչների սեփականությունը:
  • Օգտագործում է հղման հաշվիչ: Հիշողությունը ազատվում է, երբ հաշվիչը դառնում է զրո:
  • Կարող է պատճենվել: Յուրաքանչյուր պատճեն ավելացնում է հաշվիչը:
  • Բարձր ծախսեր ունի համեմատ unique_ptr-ի հետ, հաշվի կառավարման համար:
// shared_ptr օրինակ
#include <memory>
#include <iostream>

int main() {
    std::shared_ptr<int> ptr1 = std::make_shared<int>(20);
    std::cout << *ptr1 << " (use_count: " << ptr1.use_count() << ")" << std::endl; // 20 (use_count: 1)
    std::shared_ptr<int> ptr2 = ptr1; // պատճենում, ավելացնում է use_count
    std::cout << *ptr1 << " (use_count: " << ptr1.use_count() << ")" << std::endl; // 20 (use_count: 2)
    std::shared_ptr<int> ptr3 = ptr1; // ևս մեկ պատճեն
    std::cout << *ptr1 << " (use_count: " << ptr1.use_count() << ")" << std::endl; // 20 (use_count: 3)
    return 0;
}

std::weak_ptr

  • Չի տիրապետում ռեսուրսին և չի ավելացնում հաշվիչը:
  • Օգտագործվում է shared_ptr-ների միջև ցիկլային հղումներից խուսափելու համար:
  • Հնարավորություն է տալիս մուտք գործել ռեսուրսին, որի վրա ցույց է տալիս shared_ptr, բայց չի խոչընդոտում նրա հեռացմանը:
  • Մուտք գործելու համար անհրաժեշտ է weak_ptr-ը փոխարկել shared_ptrlock() մեթոդով:
// weak_ptr օրինակ
#include <memory>
#include <iostream>

int main() {
    std::shared_ptr<int> shared_ptr_int = std::make_shared<int>(30);
    std::weak_ptr<int> weak_ptr_int = shared_ptr_int;

    if (auto locked_ptr = weak_ptr_int.lock()) {
        std::cout << *locked_ptr << std::endl; // 30
    } else {
        std::cout << "Ռեսուրսը արդեն հեռացվել է." << std::endl;
    }

    shared_ptr_int.reset(); // Ռեսուրսը ազատվում է

    if (auto locked_ptr = weak_ptr_int.lock()) {
        std::cout << *locked_ptr << std::endl;
    } else {
        std::cout << "Ռեսուրսը արդեն հեռացվել է." << std::endl; // Ռեսուրսը արդեն հեռացվել է
    }
    return 0;
}

Օգտագործելով խելացի ցուցիչները՝ դա լավ պրակտիկա է ժամանակակից C++-ում, քանի որ դա զգալիորեն նվազեցնում է հիշողության կառավարման սխալների հավանականությունը։