Sobes.tech
Middle+
235

shared_ptr-те есептегіш қалай жұмыс істейді?

AI-дан жауап

sobes.tech AI

std::shared_ptr қолданғанда екі санауыш пайдаланылады:

  1. Use count (Сілтеме санауышы): Атомар санақ, ол жаңа shared_ptr көшірмесі жасалғанда, ол бірдей объектке көрсететін, инкременттеледі және shared_ptr жойылғанда декременттеледі. Егер нөлге жетсе, shared_ptr көрсететін объект жойылады.
  2. Weak count (Слаб сілтемелер санауышы): Атомар санақ, ол std::weak_ptr құрылғанда, ол инкременттеледі және weak_ptr жойылғанда декременттеледі. Егер нөлге жетсе, басқару блогы (control block), ол екі санауышты да қамтиды, жойылады.

Бұл санауыштар басқару блогында сақталады, ол динамикалық түрде бірінші рет shared_ptr объектісі жасалғанда бөлінеді. Басқару блогы сонымен қатар объект үшін deleter және allocator қамтуы мүмкін.

Атомар санауыштарды пайдалану көп ағынды қауіпсіздікті қамтамасыз етеді, shared_ptr көшірмелері мен жою кезінде әртүрлі ағындардан. Алайда, shared_ptr көрсететін объектке қол жеткізу көп ағынды қауіпсіз емес, егер объект бастапқыда қауіпсіз болмаса.

// Санауыштарды басқаруды көрсететін мысал
struct MyObject {
    int data;
    MyObject(int d) : data(d) { /* ... */ }
    ~MyObject() { /* ... */ } // Деструктор use_count == 0 болғанда шақырылады
};

int main() {
    std::shared_ptr<MyObject> sp1 = std::make_shared<MyObject>(10);
    // use_count == 1, weak_count == 0

    std::shared_ptr<MyObject> sp2 = sp1;
    // use_count == 2, weak_count == 0

    std::weak_ptr<MyObject> wp1 = sp1;
    // use_count == 2, weak_count == 1

    sp1.reset();
    // use_count == 1, weak_count == 1 (объект әлі өмір сүріп жатыр)

    {
        std::shared_ptr<MyObject> sp3 = wp1.lock();
        // Объект әлі бар, sp3 жасалды
        // use_count == 2, weak_count == 1
    } // sp3 аймағынан шығады
    // use_count == 1, weak_count == 1

    sp2.reset();
    // use_count == 0, weak_count == 1 (объект жойылды!)

    wp1.reset(); // weak_ptr жойылды
    // use_count == 0, weak_count == 0 (басқару блогы жойылды)

    return 0;
}