Sobes.tech
Middle

std::shared_ptr'деги шилтемелердин саноочу кандай иштейт?

sobes.tech AI

AIден жооп

std::shared_ptrтүн шилтемелеринин саноолору өзүнчө объектте сакталат — башкаруу блогунда (control block).

Бул башкаруу блогу түзүлөт:

  • std::shared_ptr биринчи жолу түзүлгөндө көрсөткүчтөн.
  • Колдонуучу тарабынан жуугуч же аллокатор менен түзүлгөндө.
  • std::make_shared же std::allocate_shared колдонулганда.

Бул башкаруу блогунда кеминде эки эсептегич болот:

  1. Катуу шилтемелердин эсептегичи (strong count): std::shared_ptr түзүлгөндө же көчүрүлгөндө көбөйөт, жок кылынганда азаяды. Эгер бул эсептегич нөлгө жетсе, башкарылуучу объект бошотулат.
  2. Слаб шилтемелердин эсептегичи (weak count): std::weak_ptr түзүлгөндө көбөйөт, жок кылынганда азаяды. Эгер эки эсептегич — катуу жана слаб — нөлгө жетсе, башкаруу блогу бошотулат.

std::make_shared колдонуу түздөн-түз new менен түзүүдөн артыкчылыкка ээ, анткени ал объектти жана башкаруу блогун бир эле эс тутум бөлүмүндө алоқа кылып, иштөөчәндикти жакшыртат жана фрагментацияны азайтат.

Атомик эсептегичтер std::shared_ptr-ди көптөгөн агымдарда колдонууга коопсуз кылат, бирок башкарылуучу объектке кирүү алдын ала синхрондоштурулбайт.

Мисал:

#include <iostream>
#include <memory>

struct MyObject {
    int data;
    MyObject(int d) : data(d) {
        std::cout << "MyObject(" << data << ") түзүлдү\n";
    }
    ~MyObject() {
        std::cout << "MyObject(" << data << ") жок кылынды\n";
    }
};

int main() {
    std::shared_ptr<MyObject> ptr1 = std::make_shared<MyObject>(10);
    // катуу эсептегич: 1, слаб эсептегич: 0

    {
        std::shared_ptr<MyObject> ptr2 = ptr1;
        // катуу эсептегич: 2, слаб эсептегич: 0

        std::weak_ptr<MyObject> weak_ptr = ptr1;
        // катуу эсептегич: 2, слаб эсептегич: 1

        if (auto locked_ptr = weak_ptr.lock()) {
            // катуу эсептегич: 3, слаб эсептегич: 1 (lock ичинде)
            std::cout << "Объект маалыматтары: " << locked_ptr->data << std::endl;
        }
        // катуу эсептегич: 2, слаб эсептегич: 1
    } // ptr2 аймактан чыгат
    // катуу эсептегич: 1, слаб эсептегич: 1

    // Объект дагы жок кылынган эмес, анткени катуу эсептегич 1

    {
        std::weak_ptr<MyObject> weak_ptr2 = ptr1;
        // катуу эсептегич: 1, слаб эсептегич: 2
    } // weak_ptr2 аймактан чыгат
    // катуу эсептегич: 1, слаб эсептегич: 1

} // ptr1 аймактан чыгат
// катуу эсептегич: 0, слаб эсептегич: 1
// Объект жок кылынат, анткени катуу эсептегич 0 болду
// Башкаруу блогу калганча, слаб эсептегич 0 болбосо, калат