Sobes.tech
Middle

Чӣ тавр ҳисобкунаки истинод дар std::shared_ptr кор мекунад?

sobes.tech AI

Ҷавоб аз AI

Шумораи истинодҳо дар std::shared_ptr дар объекти алоҳида нигоҳ дошта мешавад — блоки идоракунӣ (control block).

Блоки идоракунӣ сохта мешавад:

  • Дар аввалин бор, вақте ки std::shared_ptr аз нишондиҳанда сохта мешавад.
  • Вақте ки std::shared_ptr бо тозакунанда ё аллокатори корбар сохта мешавад.
  • Вақте ки std::make_shared ё std::allocate_shared истифода мешавад.

Ин блоки идоракунӣ ҳадди ақал ду ҳисобкунак дорад:

  1. Ҳисобкунаки пайвандҳои қавӣ (strong count): Вақте ки std::shared_ptr сохта ё нусхабардорӣ мешавад, зиёд мешавад. Вақте ки std::shared_ptr нест карда мешавад, кам мешавад. Вақте ки ин ҳисобкунак ба сифр мерасад, объекти идорашаванда озод мешавад.
  2. Ҳисобкунаки пайвандҳои заъиф (weak count): Вақте ки std::weak_ptr аз std::shared_ptr сохта мешавад, зиёд мешавад. Вақте ки 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 << ") created\n";
    }
    ~MyObject() {
        std::cout << "MyObject(" << data << ") destroyed\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 << "Object data: " << 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
// Объект нест карда мешавад, зеро ҳисобкунаки қавӣ ба сифр расид
// Блоки идоракунӣ то вақте ки ҳисобкунаки заъиф ба сифр нарасад, боқӣ мемонад